antoniolg / androidmvp

MVP Android Example
5.93k stars 1.58k forks source link

I'd like to create Mockito tests for the LoginPresenterImpl #26

Closed spark85 closed 6 years ago

spark85 commented 7 years ago

Basically, the title says it all. If I create the tests can I make a pull request?

spark85 commented 7 years ago

I've started building out Mockito tests, and I've run into an issue with the ArguementCaptor. Here is a code sample.

@Test
public void testValidateCredentialsCallsLogin() {
    ArgumentCaptor<String> usernameCaptor = forClass(String.class);
    ArgumentCaptor<String> passwordCaptor = forClass(String.class);
    ArgumentCaptor<LoginInteractor.OnLoginFinishedListener> loginInteractorArgumentCaptor =     forClass(LoginInteractor.OnLoginFinishedListener.class);
    loginPresenter.validateCredentials(eq("username"), eq("password"));
    verify(loginInteractor, times(1)).login(usernameCaptor.capture(),
                                            passwordCaptor.capture(),
                                            loginInteractorArgumentCaptor.capture());

    assertThat(usernameCaptor.getValue(), is("username"));
    assertThat(passwordCaptor.getValue(), is("password"));
    assertThat(loginInteractorArgumentCaptor.getValue(),is((LoginInteractor.OnLoginFinishedListener) loginPresenter));
}

I've made a post about it in the Mockito google groups here. https://groups.google.com/forum/#!topic/mockito/Mao-dr0303I I've tried different variations of argument matchers but I keep running into the same error:

No argument value was captured! You might have forgotten to use argument.capture() in verify()... ...or you used capture() in stubbing but stubbed method was not called. Be aware that it is recommended to use capture() only with verify()

Examples of correct argument capturing: ArgumentCaptor argument = ArgumentCaptor.forClass(Person.class); verify(mock).doSomething(argument.capture()); assertEquals("John", argument.getValue().getName());

In my sample it looks like all conditions are met. I'm only using matchers as arguments, I'm calling verify on a stub, the LoginInteractor, and the stubbed method is called.

Any ideas?

Thank you, David

antoniolg commented 7 years ago

You don't need to use argument captors for that. You can simply do:

verify(loginInteractor.login("username", "password", any(LoginInteractor.OnLoginFinishedListener.class));

Thats a rough approach ^, so probably won't compile exactly with that code.

For what you're trying to test, you don't need to even validate the listener.

Regarding your question, if tests are valid, I'm perfectly OK with merging your PR.

CazimirRoman commented 6 years ago

Hi,

I am experiencing a similar problem described here: https://stackoverflow.com/questions/51797291/argumentcaptor-captures-wrong-class

It basically the same thing you had in your test but i need to mock the behaviour of my callback interface to simulate login error or login success. Do you have any idea what is wrong on my side?

Thanks a bunch!