Mockito ArgumentMatcher 说参数不同

新手上路,请多包涵

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

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

 verify(myDAO, times(1)).update(argThat(new StatusMatcher("SomeStatus")));

这里 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
);

请注意,这对除一个测试用例之外的所有测试用例都适用。所以我知道 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());
    }
}

原文由 Mustafa Hussain 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 807
2 个回答

就像你说的,它失败了,因为论点不同。看看下面的测试,您会发现第二种测试方法将失败,因为您的 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")));
    }
}

我可以大胆猜测您可能正在重用变量,或者有一个静态字段等。但是如果没有看到您的测试代码,没有人能说出来。

原文由 Morfic 发布,翻译遵循 CC BY-SA 4.0 许可协议

  • 尽量简化测试/被测代码。您真的需要改变参数并验证存根吗?这两个动作
  • 可能表示有代码味道。放宽参数验证和
  • 使用某种 any() 匹配器在

原文由 user3208935 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题