0
votes

I am trying to unit test the following method in Android:

@Override
public void onTryAgain() {
    mView.showLoading();

    mGetLoginSsoUseCase.execute(
            getLoginSsoLink(),
            new GetSsoLinkUseCase.Params(mUrl));
}

In which getLoginSsoLink() returns a callback object:

private ICallback<GetLoginSsoLinkResult> getLoginSsoLink() {
    return new ICallback<GetLoginSsoLinkResult>() {
        @Override
        public void onResult(GetLoginSsoLinkResult result) {
            // some code
        }

        @Override
        public void onKoError(KOException exception) {
            // some code
        }

        @Override
        public void onConnectivityError(ConnectivityException exception) {
            // some code
        }

        @Override
        public void onGenericError(Exception exception) {
            // some code
        }
    };
}

My unit test using Mockito is like that:

@Test
public void WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(){

    doNothing().when(mGetSsoLinkUseCase).execute(
            FAKE_GET_LOGIN_SSO_LINK_RESULT_CALLBACK,
            FAKE_GET_SSO_LINK_USE_CASE_PARAMS);

    mPresenter.onTryAgain();

    verify(mGetSsoLinkUseCase).execute(
            FAKE_GET_LOGIN_SSO_LINK_RESULT_CALLBACK,
            FAKE_GET_SSO_LINK_USE_CASE_PARAMS);
}

Where the fake vars are:

private static final ICallback<GetLoginSsoLinkResult> FAKE_GET_LOGIN_SSO_LINK_RESULT_CALLBACK =
        new ICallback<GetLoginSsoLinkResult>() {
            @Override
            public void onResult(GetLoginSsoLinkResult result) {}

            @Override
            public void onKoError(KOException exception) {}

            @Override
            public void onConnectivityError(ConnectivityException exception) {}

            @Override
            public void onGenericError(Exception exception) {}
        };
private static final GetSsoLinkUseCase.Params FAKE_GET_SSO_LINK_USE_CASE_PARAMS =
        new GetSsoLinkUseCase.Params(FAKE_SSO_URL);

If I run the test, I get the following error:

Argument(s) are different! Wanted: mGetSsoLinkUseCase.execute( com.xxx.xxxforstores.presenter.LoginSsoPresenterTest$1@8317c52, com.xxx.xxxforstores.domain.usecase.GetSsoLinkUseCase$Params@68e965f5 ); -> at com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111) Actual invocation has different arguments: mGetSsoLinkUseCase.execute( com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter$1@76f2bbc1, com.xxx.xxxforstores.domain.usecase.GetSsoLinkUseCase$Params@6f27a732 ); -> at com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter.onTryAgain(LoginSsoPresenter.java:115)

Comparison Failure:

Argument(s) are different! Wanted: mGetSsoLinkUseCase.execute( com.xxx.xzzforstores.presenter.LoginSsoPresenterTest$1@8317c52, com.xxx.xxzforstores.domain.usecase.GetSsoLinkUseCase$Params@68e965f5 ); -> at com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111) Actual invocation has different arguments: mGetSsoLinkUseCase.execute( com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter$1@76f2bbc1, com.xxx.xxxforstores.domain.usecase.GetSsoLinkUseCase$Params@6f27a732 ); -> at com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter.onTryAgain(LoginSsoPresenter.java:115)

at com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

I have a little experience in unit test so I figure that I am probably doing something wrong, what I have to change to test a method like that?

1

1 Answers

0
votes

1) If mGetLoginSsoUseCase is a mock then you do not really need to set-up the .execute method with doNothing. Nothing will happen by default anyway

2) You cant really go for exact objects in the verify as one of the params is simply created on the fly: new GetSsoLinkUseCase.Params(mUrl). I would go for any(class) checks which should be enough in your case:

verify(mGetSsoLinkUseCase).execute(
            Mockito.any(ICallback.class),
            Mockito.any(GetSsoLinkUseCase.Params.class));