Mockito问题 - InvalidUseOfMatchersException

时间:2014-07-24 15:10:33

标签: java testing mockito

我正在使用mockito进行测试,但我遇到了这个问题:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at cl.gps.tms.planifications.planification.test.PlanificationCreateTest.setUp(PlanificationCreateTest.java:68)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

...

PlanificationCreateTest使用SimpleQueryBus创建一个通用查询,其中de first参数指示返回的对象类型,第二个参数是查询的过滤器。

我想要存根SimpleQueryBus类(外部库)返回null(仅限现在)

SimpleQueryBus代码

public class SimpleQueryBus implements QueryBus {

    public <T, R> R handle(Class<R> clazz, T query) throws Exception {
    ...
    }
}

我的测试代码

public class PlanificationCreateTest {

    private QueryBus queryBus;

    @Before
    public void setUp() throws Exception {
        queryBus = Mockito.mock(SimpleQueryBus.class);

        when(queryBus.handle(VehicleCollection.class, any(GetVehicle.class))).thenAnswer(null);

        ....
    }
}

更新(已解决):

public class PlanificationCreateTest {

    private QueryBus queryBus;

    @Before
    public void setUp() throws Exception {
        queryBus = Mockito.mock(SimpleQueryBus.class);

        // first example
        when(queryBus.handle(any(Class.class), isA(VehicleAvailable.class))).thenReturn(null);          

        // second example
        vehicle = new VehicleCollection("001", "name", "tag", "brand", "model");            
        when(queryBus.handle(any(Class.class), isA(GetVehicle.class))).thenReturn(vehicle);

        ....
    }
}

...谢谢

3 个答案:

答案 0 :(得分:9)

这是因为您使用any()以及VehicleCollection.class类型的真实参数Class<VehicleCollection>

如下所示更改它,你应该没问题:

 when(queryBus.handle(any(VehicleCollection.class), any(GetVehicle.class))).thenAnswer(null);

Mockito解释了原因:http://mockito.googlecode.com/svn/tags/1.7/javadoc/org/mockito/Matchers.html

  

如果您使用参数匹配器,则必须提供所有参数   由匹配者。

     

例如:(示例显示验证,但同样适用于存根):

    // Correct - eq() is also an argument matcher
    verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));


    // Incorrect - exception will be thrown because third argument is given without argument matcher.
    verify(mock).someMethod(anyInt(), anyString(), "third argument");    

答案 1 :(得分:1)

这也是EasyMock

的问题

基本上,只要在一个参数上使用Matcher,就需要在所有参数上使用它们

when(queryBus.handle(isA(VehicleCollection.class), any(GetVehicle.class))).thenAnswer(null);

应该工作

我添加了isA(Class),它创建了一个匹配器,以确保参数类型与给定的类匹配。

答案 2 :(得分:1)

when子句更改为

when(queryBus.handle(eq(VehicleCollection.class), any(GetVehicle.class))) ....

如果使用一个匹配器,则每个参数必须是匹配器。在这种情况下,第一个参数必须是Class<R>类型的匹配器。因此,请勿使用isAany,因为他们会为您提供VehicleCollection类型。相反,您需要eq