Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何对使用JavaUUID的代码进行单元测试?_Java_Unit Testing_Uuid - Fatal编程技术网

如何对使用JavaUUID的代码进行单元测试?

如何对使用JavaUUID的代码进行单元测试?,java,unit-testing,uuid,Java,Unit Testing,Uuid,我有一段代码,希望用Java UUID(UUID.randomUUID())填充响应对象的一个属性 如何从外部对代码进行单元测试以检查这种行为?我不知道里面会生成什么UUID 需要测试的示例代码: // To test whether x attribute was set using an UUID // instead of hardcode value in the response class A { String x; String y; } // Method to tes

我有一段代码,希望用Java UUID(
UUID.randomUUID()
)填充响应对象的一个属性

如何从外部对代码进行单元测试以检查这种行为?我不知道里面会生成什么UUID

需要测试的示例代码:

// To test whether x attribute was set using an UUID
// instead of hardcode value in the response
class A {
  String x;
  String y;
}

// Method to test
public A doSomething() {
  // Does something
  A a = new A();
  a.setX( UUID.randomUUID());
  return a;
}

Powermock和静态模拟是前进的方向。您将需要以下内容:

    ...
    import static org.junit.Assert.assertEquals;
    import static org.powermock.api.mockito.PowerMockito.mockStatic;
    ...

    @PrepareForTest({ UUID.class })
    @RunWith(PowerMockRunner.class)
    public class ATest
    {
    ...
      //at some point in your test case you need to create a static mock
      mockStatic(UUID.class);
      when(UUID.randomUUID()).thenReturn("your-UUID");
    ...
    }
注意:静态模拟可以在一个用@Before注释的方法中实现,因此它可以在所有需要UUID的测试用例中重用,以避免代码重复

初始化静态模拟后,可以在测试方法中的某个位置断言UUID的值,如下所示:

A a = doSomething();
assertEquals("your-UUID", a.getX());

当您需要模拟时,类/静态方法会成为一个真正的难题。我最后做的是使用一个瘦包装器类和一个实现静态方法的接口,这样可以避免使用模拟系统

在代码中,实例化/注入并使用包装器类而不是静态方法。这样,您就可以用mock替换它。

关于,似乎我能够使UUID成功模拟的唯一方法是,如果我在
@PrepareForTesting
下添加了我想要测试的类:

@PrepareForTesting({UUIDProcessor.class})
@RunWith(PowerMockitoRunner.class)
public class UUIDProcessorTest {
    // tests
}

编辑:在获得了更多的单元测试经验之后,我会选择ThinkBonobo的答案。创建一个接口、一个伪实现和一个具体实现,如下所示:

公共接口UuidProvider{
UUID UUID();
类伪实现UuidProvider{
@凌驾
公共UUID UUID(){
返回UUID.fromString(“0000-00-00-00-000000”);
}
}
}
公共类RandomUuidProvider实现UuidProvider{
@凌驾
公共UUID UUID(){
返回UUID.randomUUID();
}
}
在测试中注入
UuidProvider.false
,在生产代码中注入
RandomUuidProvider

或在科特林:

interface UuidProvider {
    fun uuid(): UUID

    class Fake : UuidProvider {
        override fun uuid() = UUID.fromString("0000-00-00-00-000000")
    }
}

class RandomUuidProvider : UuidProvider {
    override fun uuid() = UUID.randomUUID()
}
我以前的答案如下



除了ThinkBonobo的响应之外,另一种方法是创建一个getter方法(可选地用
@VisibleForTesting
注释),例如
字符串getUUID()
可以在您在测试中定义的子类中重写。

您仍然可以检查属性是否具有可解析的UUID值…您是否尝试模拟?创建一个可以替换的
UuidGenerationStrategy
以返回预编程的值。在测试中,多次调用
doSomething()
并检查结果实例在
x
中是否有不同的值。您还可以通过
供应商
,以便在测试中使用始终返回相同UUID的供应商。我认为这也是一种可行的方法。但由于我的项目中只有一个这样的用例,而且我目前正在使用Mockito,所以我没有添加PowerMock依赖项,而是使用mock接口appraoch。我认为除非重构原始代码,否则不能使用Mockito模拟静态方法?仅为这种情况添加PowerMock依赖项不应影响现有代码,因为两个框架可以在同一个项目中共存。True。。这就是为什么我创建了一个像UUIDGenerator这样的接口,它具有GenerateUid()方法。在使用UUID.randomUUID()实现它的实际代码中,正如在测试用例中我刚刚模拟了interfaceWell一样,这是一个需要做出的折衷,或者是一行代码和重量级测试,或者是一个带有实现和轻量级测试的附加接口。您可以选择解决问题的最佳方法,但有时您可能会遇到过多的小接口。您可能只考虑实现一个具体的类,并以类似的方式模拟它。<代码> @ PraseRealTebug({ UUID.class })< /代码>没有意义,因为它是最终的系统类。因此,它总是由引导类加载器加载。PowerMock无法修改它。但是PowerMock可以代替对UUID类的调用。必须将使用
UUID
的类添加到“@PrepareForTest”。