简体   繁体   中英

Mockito match specific Class argument

I am trying to mock some resources that are generated dynamically. In order to generate these resources, we must pass in a class argument. So for example:

FirstResourceClass firstResource = ResourceFactory.create(FirstResourceClass.class);

SecondResourceClass secondResource = ResourceFactory.create(SecondResource.class);

This is well and good until I tried to mock. I am doing something like this:

PowerMockito.mockStatic(ResourceFactory.class);
FirstResourceClass mockFirstResource = Mockito.mock(FirstResourceClass.class);
SecondResourceClass mockSecondResource = Mockito.mock(SecondResourceClass.class);

PowerMockito.when(ResourceFactory.create(Matchers.<Class<FirstResourceClass>>any()).thenReturn(mockFirstResource);
PowerMockito.when(ResourceFactory.create(Matchers.<Class<SecondResourceClass>>any()).thenReturn(mockSecondResource);

It seems like the mock is being injected into the calling class, but FirstResourceClass is being send mockSecondResource , which throws a compile error.

The issue is (I think) with the use of any() (which I got from this question ). I believe I have to use isA() , but I'm not sure how to make that method call, as it requires a Class argument. I have tried FirstResourceClass.class , and that gives a compile error.

You want eq , as in:

PowerMockito.when(ResourceFactory.create(Matchers.eq(FirstResourceClass.class)))
    .thenReturn(mockFirstResource);

any() ignores the argument, and isA will check that your argument is of a certain class—but not that it equals a class, just that it is an instanceof a certain class. ( any(Class) has any() semantics in Mockito 1.x and isA semantics in 2.x.)

isA(Class.class) is less specific than you need to differentiate your calls, so eq it is. Class objects have well-defined equality, anyway, so this is easy and natural for your use-case.

Because eq is the default if you don't use matchers, this also works:

PowerMockito.when(ResourceFactory.create(FirstResourceClass.class))
    .thenReturn(mockFirstResource);

Note that newer versions of Mockito have deprecated the Matchers name in favor of ArgumentMatchers, and Mockito.eq also works (albeit clumsily, because they're "inherited" static methods).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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