似乎在某些情况下,EasyMock存根可以代替验证。举以下琐碎的例子:
A类:
public class A {
private B b;
public A(B b) {
this.b = b;
}
int main(int input) {
return b.timesThree(input + 4);
}
}
B类:
public class B {
int timesThree(int input) {
return input * 3;
}
}
A类测试:
@ExtendWith(MockitoExtension.class)
public class ATest {
@Mock
B b;
@InjectMocks
A a;
@Test
void testMain() {
doReturn(21).when(b).timesThree(7);
int result = a.main(3);
assertEquals(21, result);
verify(b).timesThree(7);
}
}
verify
调用有意义吗?when
调用已经断言b.timesThree()
的输入参数为7。
在这种情况下没有。这取决于您在测试中真正想要断言的内容。
在这里,您试图测试当用值2调用main方法时,应该会发生什么
-
timeThree应该用值+4 调用
-
timeThree返回的值应由您的主函数返回
由于在测试中,以下三行足以断言以上两种情况,因此您不需要在此处进行验证。
doReturn(21).when(b).timesThree(7);
int result = a.main(3);
assertEquals(21, result);
找出测试是否足够好的最简单方法是注释掉部分实现并使测试失败(TDD)。只要你考试不及格,你就很好。
例如:将4改为5-测试失败,删除输入测试失败
假设您的timeThree方法没有返回值,而是将其存储在的某个位置
int main(int input) {
//Stores value somwhere
b.timesThree(input + 4);
}
在这里,您必须断言timeThree被调用一次,值为7。在这种情况下,您需要进行验证,因为如果没有验证,您将永远无法获得失败的测试。
此外,在旁注中,其中一条评论提到"如果代码被返回21替换,测试将通过;">
为了证明您的测试不符合此要求,请考虑使用随机整数而不是硬编码值。这将确保在您的实现中不会出现意外的硬编码。随机整数的示例库https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/RandomUtils.html#nextInt()