Reputation: 4857
I have a method in my MainActivity
(Android) and I want to mock the A
instance :
public void some_method() {
A a = new A();
....
}
so I created a kind of factory class as such
public class SomeFactory(){
// some constructor
public A populateWithParameter(Parameter parameter){
return new A(parameter)
}
}
and the method above turns into
public void some_method(SomeFactory someFactory) {
A a = someFactory.populateWithParameter(parameter);
a.method_call()
....
}
I tried this
@Mock
SomeFactory someFactory;
public void testSomeMethod() throws Exception {
SomeFactory someFactory = new SomeFactory();
when(someFactory.populateWithParameter(
some_parameter)).thenReturn(null);
mainActivity.some_method(someFactory);
...
}
but I get this error message
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Upvotes: 0
Views: 280
Reputation: 11609
From the point of view of response of @DiscoS2, there is indeed an issue with this declaration
MockitoAnnotations.initMocks(this);
You should use instead SomeFactory someFactory = mock(SomeFactory.class)
and then follow the updated response of @DiscoS2
Upvotes: 0
Reputation: 16181
You are not mocking your factory. Also, wrong method call.
Do this instead.
SomeFactory someFactory = mock(SomeFactory.class)
when(someFactory.populateWithParameter(
some_parameter)).thenReturn(null);
mainActivity.some_method(someFactory);
UPDATE
Your code has changed so for completeness this is what your test should look like. In the updated code above, you were overwriting your mock
with a real object. Assuming your objects are correctly set up. Notice the different syntax for providing a return object. I think this is more readable.
@Mock SomeFactory mockFactory;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this); // set up annotated mocks
}
@Test
public void testSomeMethod() {
A subject = new A();
doReturn(subject).when(mockFactory)
.populateWithParameter(any(Parameter.class));
main_activity.some_method(mockFactory);
verify(mockFactory,times(1)).populateWithParameter(any(Parameter.class));
}
Best Practices
main_activity
becomes MainActivity
, some_method
becomes SomeMethod
.Upvotes: 1
Reputation: 13223
You need a way to overwrite the instance of A
from your test. Typically this is done using an injection framework. For a simple case, you can make the field under test protected
(assuming the test class is in the same package as the class under test).
The error you are seeing comes interacting with a "real" object as if it was a mock.
In this case SomeFactory
is a real object so it cannot be when()ed
Upvotes: 0