简体   繁体   English

Mockito ArgumentMatcher 说 Arguments 是不同的

[英]Mockito ArgumentMatcher saying Arguments are Different

I am using Mockito for Unit testing and I am using ArgumentMatcher to check if a particular field of an argument has a particular value.我正在使用 Mockito 进行单元测试,并且我正在使用 ArgumentMatcher 检查参数的特定字段是否具有特定值。

I have a StatusMatcher class that extends ArgumentMatcher and checks whether an object of class MyClass has a particular value in status field.我有一个 StatusMatcher class 扩展 ArgumentMatcher 并检查 class MyClass 的 object 是否在状态字段中具有特定值。 The way I am invoking this in the tests is:我在测试中调用它的方式是:

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

Here update is the method of the DAO that is getting called with some MyClass object.这里update是使用 MyClass object 调用的 DAO 的方法。 I want to see if it has the correct status or not.我想看看它是否具有正确的状态。 This is what I get:这就是我得到的:

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

Note that this is working perfectly for all the test cases except one test case.请注意,这对除一个测试用例之外的所有测试用例都有效。 So I know the StatusMatcher etc. have been coded correctly.所以我知道 StatusMatcher 等已正确编码。 I am not sure what is different about the method where its getting this exception.我不确定获得此异常的方法有什么不同。

What I want to know is: under what conditions will the ArgumentMatcher throw such exception so I can find out what I am missing (It is not for me to paste the actual method codes) Please tell me if the explanation is not clear enough, and I will try to improve it.我想知道的是:ArgumentMatcher 在什么情况下会抛出这样的异常,以便我可以找出我缺少的东西(我不能粘贴实际的方法代码)如果解释不够清楚,请告诉我,以及我会努力改进它。 Thanks for reading this far:)感谢您阅读本文:)

EDIT: Here is the code for my StatusMatcher class编辑:这是我的 StatusMatcher class 的代码

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

Like you said, it fails because the arguments are different.就像你说的,它失败了,因为论点不同。 Take a look at the test below and you'll see that the second test method will fail because the status in your MyClass instance is different from SomeStatus that you passed in the matcher.看看下面的测试,您会看到第二个测试方法将失败,因为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")));
    }
}

I could take a wild guess that you could be reusing variables, or have a static field, etc. But without seeing your test code, no one can tell.我可以疯狂地猜测您可能正在重用变量,或者有一个静态字段等。但是如果没有看到您的测试代码,没有人能说出来。

  • Try to simplify the test / code under test.尝试简化测试/被测代码。 Do you really need to mutate arguments and also verify stubbing?你真的需要改变参数并验证存根吗? Both of those actions这两个动作
  • might indicate a code smell.可能表示代码异味。 Relax the argument verification and放宽参数验证和
  • use some kind of any() matcher Perform validation of arguments in the使用某种 any() 匹配器在

For others that are facing a similar issue here is how I fixed it.对于其他面临类似问题的人来说,这是我修复它的方法。

The code below will throw the following error if you pass in a new instance of an object.如果您传入 object 的新实例,下面的代码将引发以下错误。 All you have to do in this case is create a variable since it will not create a new reference in memory.在这种情况下,您所要做的就是创建一个变量,因为它不会在 memory 中创建新的引用。

@Test
void shouldLogExceptionWithType() {
    mongoDao = mock(MongoDao.class);
    StepDetail stepDetail = StepDetail.builder()
            .table("some table")
            .batchType("Some batch type")
            .build();
    doCallRealMethod().when(mongoDao).logException(new Exception(), stepDetail.getBatchType().getName());
    mongoDao.logException(new Exception(), stepDetail.getBatchType().getName());
    verify(mongoDao, times(1)).logException(new Exception(), stepDetail.getBatchType().getName());
}

Code Fixed:代码修正:

@Test
void shouldLogExceptionWithType() {
    mongoDao = mock(MongoDao.class);
    StepDetail stepDetail = StepDetail.builder()
            .table("some table")
            .batchType("Some batch type")
            .build();
    Exception exception = new Exception();
    doCallRealMethod().when(mongoDao).logException(exception, stepDetail.getBatchType().getName());
    mongoDao.logException(exception, stepDetail.getBatchType().getName());
    verify(mongoDao, times(1)).logException(exception, stepDetail.getBatchType().getName());
}

I also faced this issue.我也遇到过这个问题。 Below is the error and its solution:以下是错误及其解决方案:

error: Argument(s) are different! Wanted:

    tradeMaintenanceDao.updateTradesMaintData(.....

I used the following statement to resolve it:我使用以下语句来解决它:

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

The original cause was:原来的原因是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM