如何从 java.util 包模拟 UUID.randomUUID()?

有什么问题UUID.randomUUID()- 它只是不能被嘲笑


可以嘲笑吗?或者我的来源有错误?


看例子:


1) 被测试的类


package com.grayen;


import java.util.UUID;


public class TestedClass {

    public UUID getUuid() {

        return UUID.randomUUID();

    }

    public UUID getUuidFromWrapper() {

        return UuidWrapper.randomUUID();

    }

}

一种方法使用 UUID 的包装器,我可以模拟该包装器!


2) 真实 UUID 的包装器(所有修饰符都相同)


package com.grayen;


import java.util.UUID;


public final class UuidWrapper {

    public static UUID randomUUID() {

        return UUID.randomUUID();

    }

}

3)测试(最后注释行抛出异常)


package com.grayen;


import org.junit.Test;

import org.junit.runner.RunWith;

import org.powermock.api.mockito.PowerMockito;

import org.powermock.core.classloader.annotations.PrepareForTest;

import org.powermock.modules.junit4.PowerMockRunner;

import java.util.UUID;

import static org.junit.Assert.assertEquals;


@PrepareForTest({UUID.class, UuidWrapper.class})

@RunWith(PowerMockRunner.class)

public class TestedClassTest {


    @Test

    public void testMethod() {

        UUID uuid = UUID.randomUUID();


        PowerMockito.mockStatic(UUID.class);

        PowerMockito.mockStatic(UuidWrapper.class);


        PowerMockito.when(UUID.randomUUID()).thenReturn(uuid);

        PowerMockito.when(UuidWrapper.randomUUID()).thenReturn(uuid);


        TestedClass testedClass = new TestedClass();


        assertEquals(uuid, testedClass.getUuidFromWrapper());

        //assertEquals(uuid, testedClass.getUuid());

    }

}


慕码人2483693
浏览 275回答 2
2回答

扬帆大鱼

模拟静态方法始终是一种脆弱的方法。如果可能,最好使用非静态 UUID 源,然后可以轻松模拟。例如:/**&nbsp;* A source of new {@link UUID} instances.&nbsp;*/public interface UuidSource {&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Returns a new {@link UuidSource} that generates UUIDs using {@link UUID#randomUUID}.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; public static UuidSource random() {&nbsp; &nbsp; &nbsp; &nbsp; return UUID::randomUUID;&nbsp; &nbsp; }&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Returns a new {@link UUID} instance.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* <p>The returned value is guaranteed to be unique.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; UUID newUuid();}然后你可以将它注入TestedClass,或者TestedClass拥有一个私有成员:public class TestedClass {&nbsp; &nbsp; private UuidSource uuidSource = UuidSource.random();&nbsp; &nbsp; public UUID getUUID() {&nbsp; &nbsp; &nbsp; &nbsp; return uuidSource.newUuid();&nbsp; &nbsp; }&nbsp; &nbsp; // etc.}然后要测试它,您可以使用仅测试构造函数,以允许注入模拟UuidSource,或者您可以uuidSource直接替换字段的值(通过扩大其可见性或使用反射或其他方式)。作为奖励:这将您的实际生产代码与UUID.randomUUID(). 如果稍后您决定需要使用第 2 版 UUID(基于日期时间)或其他版本而不是随机 UUID,您也可以在生产代码中轻松更改它。这就是人们所说的使您的代码更具可测试性通常会导致更好的整体设计的意思。

森栏

所以我拿了你的代码并让它工作。您需要做的就是添加TestedClass.class到您的@PrepareForTest.package com.grayen;import org.junit.Test;import org.junit.runner.RunWith;import org.powermock.api.mockito.PowerMockito;import org.powermock.core.classloader.annotations.PrepareForTest;import org.powermock.modules.junit4.PowerMockRunner;import java.util.UUID;import static org.junit.Assert.assertEquals;@PrepareForTest({&nbsp; &nbsp; UUID.class,&nbsp;&nbsp; &nbsp; UuidWrapper.class,&nbsp;&nbsp; &nbsp; TestedClass.class})@RunWith(PowerMockRunner.class)public class TestedClassTest {&nbsp; &nbsp; @Test&nbsp; &nbsp; public void testMethod() {&nbsp; &nbsp; &nbsp; &nbsp; UUID uuid = UUID.randomUUID();&nbsp; &nbsp; &nbsp; &nbsp; PowerMockito.mockStatic(UUID.class);&nbsp; &nbsp; &nbsp; &nbsp; PowerMockito.mockStatic(UuidWrapper.class);&nbsp; &nbsp; &nbsp; &nbsp; PowerMockito.when(UUID.randomUUID()).thenReturn(uuid);&nbsp; &nbsp; &nbsp; &nbsp; PowerMockito.when(UuidWrapper.randomUUID()).thenReturn(uuid);&nbsp; &nbsp; &nbsp; &nbsp; TestedClass testedClass = new TestedClass();&nbsp; &nbsp; &nbsp; &nbsp; assertEquals(uuid, testedClass.getUuidFromWrapper());&nbsp; &nbsp; &nbsp; &nbsp; assertEquals(uuid, testedClass.getUuid());&nbsp; &nbsp; }}编辑我没有看到评论,但k5_指出了它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java