如何对使用JavaUUID的代码进行单元测试?
我有一段代码,希望用Java UUID(如何对使用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
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”。