如何对使用Java UUID的代码进行unit testing?

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

如何从外部对此代码进行unit testing以检查此行为? 我不知道将在其中生成的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()); 

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

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

当你需要模拟时,类/静态方法成为一种真正的痛苦。 我最终做的就是使用一个模拟系统来节省你使用一个瘦的包装类和一个实现静态方法的接口。

在您的代码中,实例化/注入和使用包装类而不是静态方法。 这样你可以用模拟代替它。

除了ThinkBonobo的响应之外,还有另一种创建getter方法(可选择使用@VisibleForTesting注释)的方法,例如String getUUID() ,它可以在您在测试中定义的子类中重写。