Mockito ArgumentMatcher说争论是不同的。

时间:2021-02-08 05:28:05

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. The way I am invoking this in the tests is:

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

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. I want to see if it has the correct status or not. This is what I get:

这里更新是使用一些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
);

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. I am not sure what is different about the method where its getting this exception.

注意,这对于所有的测试用例来说都是完美的,除了一个测试用例。我知道StatusMatcher等已经被正确编码了。我不确定这种方法的不同之处是什么。

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. Thanks for reading this far :)

我想知道的是:在什么条件下会ArgumentMatcher抛出这样的异常,所以我可以找到我丢失的(对我来说不是粘贴实际方法代码)请告诉我解释不够清楚,我将试图改进它。感谢您阅读这篇文章

EDIT: Here is the code for my StatusMatcher class

编辑:这是我的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());
    } 
}

2 个解决方案

#1


6  

Like you said, it fails because the arguments are different. Take a look at the test bellow and you'll see that the the second test method will fail because the status in your MyClass instance is different from SomeStatus that you passed in the matcher.

就像你说的,它失败了,因为争论是不同的。看看测试bellow,您会发现第二个测试方法会失败,因为MyClass实例中的状态与您在matcher中传递的某些状态不同。

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.

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

#2


0  

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

#1


6  

Like you said, it fails because the arguments are different. Take a look at the test bellow and you'll see that the the second test method will fail because the status in your MyClass instance is different from SomeStatus that you passed in the matcher.

就像你说的,它失败了,因为争论是不同的。看看测试bellow,您会发现第二个测试方法会失败,因为MyClass实例中的状态与您在matcher中传递的某些状态不同。

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.

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

#2


0  

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