Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 447
Ajayc Avatar asked Jan 05 '23 00:01

Ajayc


1 Answers

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

like image 69
Jeff Bowman Avatar answered Jan 13 '23 21:01

Jeff Bowman