Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 莫基托';s@After和verifynomore交互_Java_Junit_Mockito - Fatal编程技术网

Java 莫基托';s@After和verifynomore交互

Java 莫基托';s@After和verifynomore交互,java,junit,mockito,Java,Junit,Mockito,我想确保每个测试都用它的mock来验证所有的交互,所以我只是添加了一个带有@After注释的方法,其中带有一个verifyNoMoreInteractions,所有的mock都作为参数 @After public void after(){ verifyNoMoreInteractions(mock1,mock2,mock3,...) } 它可以工作,但是如果在没有预期的情况下发生交互,您如何知道哪个测试是有问题的?@After在该类的每个测试完成后立即执行。不管测试是否失败。然后,如果在

我想确保每个测试都用它的mock来验证所有的交互,所以我只是添加了一个带有@After注释的方法,其中带有一个verifyNoMoreInteractions,所有的mock都作为参数

@After
public void after(){
  verifyNoMoreInteractions(mock1,mock2,mock3,...)
}

它可以工作,但是如果在没有预期的情况下发生交互,您如何知道哪个测试是有问题的?

@After
在该类的每个测试完成后立即执行。不管测试是否失败。然后,如果在
@After
方法中发生错误,它可以覆盖/隐藏在测试方法中发生的错误

请注意,
@AfterClass
是在该类的所有测试完成后执行的

一般来说,我发现将行为测试分为三部分是一种很好的方式——称之为a/a/a或称之为给定/何时/然后

安排/给定部分: 设置对象和行为

行动或时间: 执行实现

断言或断言:
验证行为和结果(提示:这就是
verifyNoMoreInteractions
去的地方)

您误用了方法
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());
    }

}

该规则将应用于每个测试。

对于JUnit5,可以在每个HmethodAdapter之后使用
,检查测试是否引发异常。如果是,则不验证模拟:

public class MockAwareTest {

    @RegisterExtension
    public MockVerifier mockVerifier = new MockVerifier();


    @BeforeEach
    void setUp() {
        mockVerifier.addMocks(...);
    }

}
以及
模拟验证器

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());
        }
    }

}
public类MockVerifier在每个methodadapter之后实现{
private final List mocks=new LinkedList();
公共void addmock(最终对象…mock){
mocks.addAll(asList(mock));
}
@凌驾
public void invokeAfterEachMethod(
最终扩展上下文上下文,
最终扩展注册表(注册表){
//如果测试没有失败,请检查模拟
if(context.getExecutionException().isEmpty()){
验证NoMoreInteractions(mocks.toArray());
}
}
}

实际上,我遵循给定的/When/Then安排,在Then部分我像往常一样放置了verify,但是因为我想确保每个创建测试的人都验证所有交互,所以我认为在@After方法中使用verifynomore交互可能是个好主意。你可以这样做,为什么不可以呢。但我喜欢在测试本身中设置大多数资源,因此After方法不会知道我要测试的模拟。是的,我一直都是这样做的,但有些测试太大了,所以我考虑将模拟作为类的属性,而不是在每个测试中声明它们,然后我考虑了@After方法中的verifyNoMoreInteractions如果测试太大,我会检查类/方法是否做得太多,关键字分离concernsCheck我的更新答案。看起来这正是你所需要的。喜欢它,但是你怎么知道哪个测试失败了呢?规则会让它失败的。所以它看起来就像它自己失败了一样。与在每个测试中放置验证器的效果相同。是否有方法知道哪个测试缺少验证?如果在测试类中声明
@规则
,则in将应用于所有带有
@test
注释的方法。我实际上是指将失败的测试显示为错误消息的一部分:@覆盖受保护的void successed(Description Description){mocks.stream().forEach((mock)->{try{verifynomoreiversations(mock);}catch(NoInteractionsWanted){System.err.println(“失败的测试”+Description.getDisplayName());抛出e;}}};}
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());
        }
    }

}