简体   繁体   English

使用Mockito | Android对调用私有回调的方法进行单元测试

[英]Unit test a method with a call to a private callback using Mockito|Android

I am trying to unit test the following method in Android: 我正在尝试对Android中的以下方法进行单元测试:

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

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

In which getLoginSsoLink() returns a callback object: 在其中getLoginSsoLink()返回一个回调对象:

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: 我使用Mockito进行的单元测试如下:

@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: 伪造的var是:

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 ); 希望: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 ); -> com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111)的实际调用具有不同的参数:mGetSsoLinkUseCase.execute(com.xxx.xxxforstores.mvp.Preter.com $ 1. $ 1。 xxxforstores.domain.usecase.GetSsoLinkUseCase$Params@6f27a732); -> at com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter.onTryAgain(LoginSsoPresenter.java:115) -> 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 ); 希望: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 ); -> com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111)的实际调用具有不同的参数:mGetSsoLinkUseCase.execute(com.xxx.xxxforstores.mvp.Preter.com $ 1. $ 1。 xxxforstores.domain.usecase.GetSsoLinkUseCase$Params@6f27a732); -> at com.xxx.xxxforstores.mvp.presenter.LoginSsoPresenter.onTryAgain(LoginSsoPresenter.java:115) -> 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) a 在com.xxx.xxxforstores.presenter.LoginSsoPresenterTest.WhenCallOnTryAgain_ThenShowLoadingIsCalledInView(LoginSsoPresenterTest.java:111)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke .org的java.lang.reflect.Method.invoke(Method.java:498)的org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)的.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) .org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)在org.junit.internal.runners.statements.InvokeMethod org.junit.internal.runners.statements的.evaluate(InvokeMethod.java:17),org.org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)的RunBefores.evaluate(RunBefores.java:26)。 junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)一个 t 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 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)处的org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java :71),位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288),位于org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58),位于org.junit.runners.ParentRunner $ 2.evaluate( org.junit.runners.ParentRunner.run(ParentRunner.java:363)的org.mockito.internal.runners.DefaultInternalRunner $ 1.run(DefaultInternalRunner.java:78)的org.mockito.internal的ParentRunner.java:268)。 org.org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)的org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)的Runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84) com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)上的.junit.runner.JUnitCore.run(JUnitCore.java:137)com.intellij.rt.execution.junit.IdeaTestRunner上的.junit.runner.JUnitCore.run(JUnitCore.java:137) $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) com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)上的com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java)上的$ Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) :70)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在java.lang处sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)处sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)上反映.Method.invoke(Method.java:498)

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) If mGetLoginSsoUseCase is a mock then you do not really need to set-up the .execute method with doNothing . 1)如果mGetLoginSsoUseCase是模拟的,那么您实际上不需要使用doNothing设置.execute方法。 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) . 2)您不能真正在verify寻找确切的对象,因为其中一个参数是在运行中简单创建的: new GetSsoLinkUseCase.Params(mUrl) I would go for any(class) checks which should be enough in your case: 我会去做any(class)检查,在您的情况下应该足够了:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Mockito对链式方法调用进行单元测试 - How to unit test chained method call(s) using Mockito 使用Mockito进行插入方法的单元测试 - unit test for insertion method using mockito Mockito InvalidUseOfMatchersException,尝试使用自定义Callback作为参数对测试方法进行单元化时 - Mockito InvalidUseOfMatchersException, when trying to unit test method with custom Callback as a parameter 如何使用junit和Mockito使用私有方法测试以下类,这里我不能使用powermockito进行私有方法调用 - how to test the following class with private methods using junit and Mockito, here i cannot use powermockito for private method call Android Unit Test为Mockito存根方法提供了非模拟消息 - Android Unit Test giving not mocked message for a Mockito stubbed method Java单元测试 - 如何使用mockito答案对异步方法(使用回调)进行单元测试 - Java unit testing - how to unit test an async method (uses callback) with mockito answer Android:JUnit + Mockito,测试回调? - Android: JUnit + Mockito, test callback? 使用Retrofit和Mockito进行Android单元测试 - Android Unit Test with Retrofit and Mockito 如何使用 mockito 使用回调测试来自 Kafka Producer 的 send 方法? - How to test the send method from a Kafka Producer with callback using mockito? 使用Mockito调用多个其他方法的方法的单元测试 - Unit test for method that calls multiple other methods using Mockito
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM