AnyString() 作为单元测试的参数

6 java junit mockito powermock assertj

我必须处理一个没有测试的遗留应用程序。因此,在开始重构之前,我想确保一切都按原样运行。

现在想象一下以下情况:

public SomeObject doSomething(final OtherObject x, final String something) {
    if(x == null) throw new RuntimeException("x may not be null!");
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在我想测试该空检查,以确保它有效并且重构后我不会丢失它。

所以我这样做了

@Test(expected = RuntimeException.class)
public void ifOtherObjectIsNullExpectRuntimeException() {
    myTestObject.doSomething(null, "testString");
}
Run Code Online (Sandbox Code Playgroud)

现在,这当然有效。

但我想传递一个随机字符串,而不是“testString”。

所以我尝试了:

@Test(expected = RuntimeException.class)
public void ifOtherObjectIsNullExpectRuntimeException() {
    myTestObject.doSomething(null, Mockito.anyString());
}
Run Code Online (Sandbox Code Playgroud)

但这是不允许的。据我所知

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: ...您不能在验证或存根之外使用参数匹配器

我确实理解这句话的含义,但我想知道我是否仍然可以在不参数化我的测试等的情况下做我想做的事情。我唯一可以使用的库是 Junit、AssertJ、Mockito 和 Powermock。

有任何想法吗?

Cod*_*ice 5

测试应该是确定性的。在测试中使用随机值使得在调试失败的测试时很难重现行为。我建议您String为测试创建一个常量,例如"abcdefg"


nas*_*kin 4

好吧,就像 Mockito 试图通过该异常告诉您一样,这并不是您真正要使用的方式anyString。这些方法只能由模拟使用。

那么,为什么不尝试使用实际的随机字符串进行测试呢?我个人最喜欢这种场景:。这实际上总是会生成一个以前从未用于测试的全新字符串。java.util.UUID.randomUUID().toString()

我还想补充一点,如果您正在为您的SomeObject类编写测试,则应该避免嘲笑SomeObject的行为。从你的例子来看,你并没有完全这样做,但看起来你可能会走那条路。模拟您尝试测试的实现的依赖项,而不是实现本身!这个非常重要; 否则你实际上并没有测试任何东西。