如何对使用 Java UUID 的代码进行单元测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36330914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I unit test code which uses Java UUID?
提问by Harish
I have a piece of code which is expected to populated one attribute of response object with Java UUID (UUID.randomUUID()
).
我有一段代码,预计会用 Java UUID ( UUID.randomUUID()
)填充响应对象的一个属性。
How can I unit test this code from outside to check this behaviour? I don't know the UUID that would be generated inside it.
如何从外部对该代码进行单元测试以检查此行为?我不知道会在其中生成的 UUID。
Sample code which needs to be tested:
需要测试的示例代码:
// 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;
}
回答by RZet
Powermock and static mocking is the way forward. You will need something like:
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");
...
}
Note the static mock can be implemented in a method annotated with @Before so it can be re-used in all test cases that require UUID in order to avoid code repetition.
请注意,静态模拟可以在用 @Before 注释的方法中实现,因此它可以在所有需要 UUID 的测试用例中重复使用,以避免代码重复。
Once the static mock is initialised, the value of UUID can be asserted somewhere in your test method as follows:
一旦静态模拟被初始化,UUID 的值可以在你的测试方法中的某处被断言,如下所示:
A a = doSomething();
assertEquals("your-UUID", a.getX());
回答by ThinkBonobo
When you need to mock, class/static methods become a real pain. What I ended up doing which will save you from using a mocking system is to use a thin wrapper class with a interface implementing the static methods.
当您需要模拟时,类/静态方法变得非常痛苦。我最终所做的将使您免于使用模拟系统的是使用带有实现静态方法的接口的瘦包装器类。
In your code, instantiate/inject and use use the wrapper class instead of the static method. That way you can replace it with mocks.
在您的代码中,实例化/注入并使用包装类而不是静态方法。这样你就可以用模拟来代替它。
回答by Makoto
In relation to this existing question, it seems like the only way I was able to get the UUID to successfully mock out is if I added the class I wanted to test under @PrepareForTesting
:
关于这个现有问题,似乎我能够成功模拟出 UUID 的唯一方法是添加我想测试的类@PrepareForTesting
:
@PrepareForTesting({UUIDProcessor.class})
@RunWith(PowerMockitoRunner.class)
public class UUIDProcessorTest {
// tests
}
回答by Eran Boudjnah
Edit: having gained more experience with unit testing, I would opt for ThinkBonobo's answer. Create an interface, a fake implementation and a concrete implementation, like so:
编辑:在单元测试方面获得了更多经验后,我会选择 ThinkBonobo 的答案。创建一个接口、一个假实现和一个具体实现,如下所示:
public interface UuidProvider {
UUID uuid();
class Fake implements UuidProvider {
@Override
public UUID uuid() {
return UUID.fromString("0000-00-00-00-000000");
}
}
}
public class RandomUuidProvider implements UuidProvider {
@Override
public UUID uuid() {
return UUID.randomUUID();
}
}
Inject UuidProvider.Fake
in your tests, and RandomUuidProvider
in your production code.
注入UuidProvider.Fake
您的测试和RandomUuidProvider
生产代码。
Or in Kotlin:
或者在 Kotlin 中:
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()
}
My old answer is below.
我的旧答案如下。
In addition to ThinkBonobo's response, another way it to create a getter method (optionally annotated with @VisibleForTesting
) such as String getUUID()
which can be overridden in a subclass you define in your test.
除了 ThinkBonobo 的响应之外,还有另一种创建 getter 方法(可选用 注释@VisibleForTesting
)的方法,例如String getUUID()
可以在您在测试中定义的子类中覆盖的方法。