Mockito ArgumentMatcher说争论是不同的

时间:2014-04-08 09:52:48

标签: java unit-testing mockito

我正在使用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());
    } 
}

3 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:1)

我也遇到过这个问题。以下是错误及其解决方案:

error: Argument(s) are different! Wanted:

    tradeMaintenanceDao.updateTradesMaintData(.....

我使用以下语句来解决它:

verify(tradeMaintenanceDao, times(1))
    .updateTradesMaintData(anyString(), anyList(), anyList(), anyString(), anyString());

原因是:

verify(tradeMaintenanceDao, times(1)).updateTradesMaintData(userName, tradeStatusList, tradeReasonList, notes, pendStatus);

答案 2 :(得分:0)

  • 尝试简化测试/被测代码。你真的需要 更改参数并验证存根?这两个动作
  • 可能表示代码有异味。放宽论证验证和
  • 使用某种any()匹配器执行
  • 中的参数验证