我有一段代码,希望用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;
}
答案 0 :(得分:9)
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());
答案 1 :(得分:3)
关于this existing question,似乎我能够让UUID成功模拟的唯一方法是,如果我在@PrepareForTesting
下添加了我想要测试的类:
@PrepareForTesting({UUIDProcessor.class})
@RunWith(PowerMockitoRunner.class)
public class UUIDProcessorTest {
// tests
}
答案 2 :(得分:2)
当你需要模拟时,类/静态方法成为一种真正的痛苦。我最终做的就是使用模拟系统来节省你使用一个瘦的包装类和一个实现静态方法的接口。
在您的代码中,实例化/注入和使用包装类而不是静态方法。这样你可以用模拟替换它。
答案 3 :(得分:0)
除了ThinkBonobo的响应之外,它是创建诸如@VisibleForTesting
之类的getter方法(可选地用String getUUID()
注释)的另一种方法,可以在测试中定义的子类中覆盖它。