Java Mockito 问题 - InvalidUseOfMatchersException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24937539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:50:58  来源:igfitidea点击:

Mockito Problems - InvalidUseOfMatchersException

javatestingmockito

提问by Hector

I am doing a test using mockito, but I am getting this problems:

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

...

The PlanificationCreateTest use the SimpleQueryBus for create a generic query where de first parameter indicates what type of object is returned, and second parameters are filters on the query.

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

I want stub the SimpleQueryBus class (external library) returning a null (only for now)

我想要存根 SimpleQueryBus 类(外部库)返回一个空值(仅现在)

The SimpleQueryBus code

SimpleQueryBus 代码

public class SimpleQueryBus implements QueryBus {

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

My test code

我的测试代码

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

        ....
    }
}

UPDATE (SOLVED):

更新(已解决):

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

        ....
    }
}

Thanks...

谢谢...

采纳答案by squallsv

This occurs because you are using any()along with a real parameter VehicleCollection.classof type Class<VehicleCollection>.

发生这种情况是因为您正在使用类型any()为实数的参数。VehicleCollection.classClass<VehicleCollection>

Change it just like below, and you should be fine:

像下面一样改变它,你应该没问题:

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

Mockito explains why: http://mockito.googlecode.com/svn/tags/1.7/javadoc/org/mockito/Matchers.html

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

If you are using argument matchers, all arguments have to be provided by matchers.

E.g: (example shows verification but the same applies to stubbing):

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

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

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

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

回答by dkatzel

This is also a problem for EasyMock

这也是一个问题 EasyMock

Basically whenever you use a Matcher on one argument, you need to use them on all the arguments

基本上每当你在一个参数上使用匹配器时,你需要在所有参数上使用它们

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

Should work

应该管用

I added isA(Class)which creates a matcher to make sure the argument type matches the given class.

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

回答by Dawood ibn Kareem

Change your whenclause to

将您的when条款更改为

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

If you use one matcher, then every argument must be a matcher. And in this case, the first argument must be a matcher of type Class<R>. So don't use isAor any, because they will give you type VehicleCollection. Instead, you need eq.

如果您使用一个匹配器,则每个参数都必须是一个匹配器。在这种情况下,第一个参数必须是 type 的匹配器Class<R>。所以不要使用isAor any,因为它们会给你 type VehicleCollection。相反,您需要eq.