我想确保每个测试都验证其模拟的所有交互,所以我只是添加了一个用@After注释的方法,并带有一个verifyNoMoreInteractions并将所有模拟作为参数。
@After
public void after(){
verifyNoMoreInteractions(mock1,mock2,mock3,...)
}
它可以工作,但是如果在没有预期的交互作用下发生交互,您怎么知道哪个测试是有问题的呢?
答案 0 :(得分:2)
@After
在此类的每次测试完成执行后立即执行。不管测试是否失败。然后,如果在@After
方法中发生错误,则可以掩盖/隐藏在测试方法中发生的错误...
请注意,@AfterClass
是在此类的所有测试完成执行之后执行的。
总的来说,我发现将行为测试分为三个部分是很好的样式-称为A / A / A或称为Given / When / Then
安排/给定的部分: 设置对象和行为
行为或时间: 执行实施
确认或然后:
验证行为和结果(提示:verifyNoMoreInteractions
的去向)
答案 1 :(得分:2)
您正在滥用方法verifyNoMoreInteractions()
。您应该在每个要验证的测试中调用它。
另一方面,@After
应该用于清理/关闭测试方法所使用的资源。
您需要的是自定义TestWatcher
规则。参见以下此类规则的示例:
public class VerifyNoMoreInteractionsRule extends TestWatcher {
private final List<Object> mocks = new ArrayList<>();
public void add(Object mock){
mocks.add(mock);
}
@Override
protected void succeeded(Description description) {
verifyNoMoreInteractions(mocks.toArray());
}
}
然后您可以在单元测试中使用它:
@RunWith(MockitoJUnitRunner.class)
public class VerifyTest {
@Rule
public VerifyNoMoreInteractionsRule noMoreInteractionsRule = new VerifyNoMoreInteractionsRule();
@Mock
private YourMock yourMock;
@Mock
private AnotherMock anotherMock;
@Before
public void setUp(){
// Register the mocks you want to verify after each test
noMoreInteractionsRule.add(yourMock);
noMoreInteractionsRule.add(anotherMock);
}
@Test
public void test(){
// Put your ordinary test code here
}
}
该规则将应用于每个测试。
答案 2 :(得分:0)
对于 JUnit5,可以使用 AfterEachMethodAdapter
来检查测试是否抛出异常。如果是,则没有验证任何模拟:
public class MockAwareTest {
@RegisterExtension
public MockVerifier mockVerifier = new MockVerifier();
@BeforeEach
void setUp() {
mockVerifier.addMocks(...);
}
}
还有MockVerifier
:
public class MockVerifier implements AfterEachMethodAdapter {
private final List<Object> mocks = new LinkedList<>();
public void addMocks(final Object... mock) {
mocks.addAll(asList(mock));
}
@Override
public void invokeAfterEachMethod(
final ExtensionContext context,
final ExtensionRegistry registry) {
// if the test didn't fail, check the mocks
if (context.getExecutionException().isEmpty()) {
verifyNoMoreInteractions(mocks.toArray());
}
}
}