Mockito ArgumentMatcher说争论是不同的

Mus*_*ain 11 java unit-testing mockito

我使用Mockito进行单元测试,我使用ArgumentMatcher来检查参数的特定字段是否具有特定值.

我有一个StatusMatcher类,它扩展了ArgumentMatcher并检查类MyClass的对象在状态字段中是否具有特定值.我在测试中调用它的方式是:

verify(myDAO, times(1)).update(argThat(new StatusMatcher("SomeStatus")));
Run Code Online (Sandbox Code Playgroud)

update是使用一些MyClass对象调用的DAO方法.我想看看它是否具有正确的状态.这就是我得到的:

Argument(s) are different! Wanted:
myDAO.update(
    <Status matcher>
);
-> at com.foo.bar.MyTest.test1 
Actual invocation has different arguments:
myDAO.update(
    com.foo.bar.MyClass
);
Run Code Online (Sandbox Code Playgroud)

请注意,除了一个测试用例之外,这适用于所有测试用例.所以我知道StatusMatcher等已经正确编码.我不确定它获得此异常的方法有什么不同.

我想知道的是:在什么条件下,ArgumentMatcher会抛出这样的异常,这样我就可以找到我所缺少的东西(这不是我粘贴实际的方法代码)请告诉我,如果解释不够清楚,并且我会尽力改进它.感谢阅读这篇远:)

编辑:这是我的StatusMatcher类的代码

    private class StatusMatcher extends ArgumentMatcher<MyClass> {

    private String status;
    public StatusMatcher(String hs) { 
        status = hs;
    }

    @Override
    public boolean matches(Object argument) {

        return status.equals(((MyClass)argument).getStatus());
    } 
}
Run Code Online (Sandbox Code Playgroud)

Mor*_*fic 10

就像你说的那样,它失败了因为参数不同.看一下下面的测试,你会发现第二个测试方法会失败,因为你MyClass实例中的状态与你SomeStatus在匹配器中传递的状态不同.

public class MatcherTest {

    class MyClass{
        private String status;

        MyClass(String status) {
            this.status = status;
        }

        public String getStatus(){
            return status;
        }
    }

    class MyDao {
        public void update(MyClass myClass){}
    }

    class StatusMatcher extends ArgumentMatcher<MyClass> {
        private String status;
        public StatusMatcher(String hs) {
            status = hs;
        }

        @Override
        public boolean matches(Object argument) {
            return status.equals(((MyClass)argument).getStatus());
        }
    }

    @Test
    public void shouldMatchStatus(){
        MyDao mock = mock(MyDao.class);
        mock.update(new MyClass("expectedStatus"));
        verify(mock, times(1)).update(argThat(new StatusMatcher("expectedStatus")));
    }

    @Test
    public void shouldNotMatchStatus(){
        MyDao mock = mock(MyDao.class);
        mock.update(new MyClass("unexpectedStatus"));
        /* THE BELLOW WILL FAIL BECAUSE ARGUMENTS ARE DIFFERENT */
        verify(mock, times(1)).update(argThat(new StatusMatcher("expectedStatus")));
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以猜测你可以重用变量,或者有一个静态字段等,但是没有看到你的测试代码,没有人能说出来.

  • 我不知道这对任何人是否有帮助,但我有时会使用诸如verify(mock).method(any(MyClass.class))之类的东西.当你传递的内容并不重要时,这很有用,可以避免这种错误. (8认同)
  • 啊! 我现在看到了.这就是它失败的原因.由于错误的措辞,我误导了.听起来好像存在类型不匹配.实际上它只是一个不同的价值.谢谢! (2认同)