Mockito - overriding a method that takes primitive parameters

I have a class that is a subclass Context. I am testing units of another class that are related to this class, and therefore I mocked it. However, I need some methods to act as their original behavior, so I'm going to β€œuntie” them.

One of them getAssets(), so I wrote this and it works correctly:

Mockito.doReturn(this.getContext().getAssets()).when(keyboard).getAssets();

keyboard is a mocked instance of the class.

Since this method takes no parameters, redefining it was quite simple.

I also need to override Context.getString(int). The parameter complicates the situation and is primitive, which further complicates the work.

I took this advice and one more, and tried to write this code:

Mockito.when(keyboard.getString(Mockito.anyInt())).thenAnswer(new Answer<String>(){
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable
         Integer arg = (Integer)invocation.getArguments()[0];
         return OuterClass.this.getContext().getString(arg.intValue());
    }
});

This is compiled and executed, but has the following exception:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at [...] <The code above>

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

For more info see javadoc for Matchers class.

at android.content.Context.getString(Context.java:282)
at [...]
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)

So, the main question: how to override methods in Mockito that have primitive parameters?

Thanks in advance

+2
source share
3 answers

You cannot drown getStringbecause it is final. Mokito cannot drown out the final methods. Just leave it unpainted and you will get its initial implementation. What do you want anyway, right?

+3
source

Shouldn't it be Answer<String>?

Mockito.when(keyboard.getString(Mockito.anyInt())).thenAnswer(new Answer<String>(){
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable {
         return "foo";
    }
});

And you could rename the keyboard -> mockContext, would that be more clear?

+1

, Context.getString() , , mockito . .

"0 matchers expected, 1 recorded" InvalidUseOfMatchersException - , final, .

, , , ; .

Finally, I decided to change and improve my design. I used the principle of separation of serialization and shared responsibilities Contextand Keyboard(I am developing the IME service). In the application itself, I passed the same object Keyboardto these two, but in the test I ridiculed Keyboardwithout any bad side effects and used TestCase.getContext()as Context, which eliminated the need to "unlock" its methods.

0
source

All Articles