相关疑难解决方法(0)

单元测试android应用程序与改造和rxjava

我已经开发了一个使用rxJava改造的Android应用程序,现在我正在尝试使用Mockito设置单元测试,但我不知道如何模拟api响应以创建不做真正的测试电话但有假响应.

例如,我想测试方法syncGenres对我的SplashPresenter工作正常.我的课程如下:

public class SplashPresenterImpl implements SplashPresenter {

private SplashView splashView;

public SplashPresenterImpl(SplashView splashView) {
    this.splashView = splashView;
}

@Override
public void syncGenres() {
    Api.syncGenres(new Subscriber<List<Genre>>() {
        @Override
        public void onError(Throwable e) {
            if(splashView != null) {
                splashView.onError();
            }
        }

        @Override
        public void onNext(List<Genre> genres) {
            SharedPreferencesUtils.setGenres(genres);
            if(splashView != null) {
                splashView.navigateToHome();
            }
        }
    });
}
}
Run Code Online (Sandbox Code Playgroud)

Api类就像:

public class Api {
    ...
    public static Subscription syncGenres(Subscriber<List<Genre>> apiSubscriber) {
        final Observable<List<Genre>> call = ApiClient.getService().syncGenres();
        return call
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(apiSubscriber);
    } …
Run Code Online (Sandbox Code Playgroud)

android mocking mockito rx-java retrofit2

17
推荐指数
1
解决办法
1万
查看次数

验证rxjava订阅者中的交互

在MVP模式中描绘您的演示者订阅返回观察者的服务的情况:

public void gatherData(){
   service.doSomeMagic()
      .observeOn(Schedulers.io())
      .subscribeOn(AndroidSchedulers.mainThread())
      .subscribe(new TheSubscriber());
}
Run Code Online (Sandbox Code Playgroud)

现在该类从视图中TheSubscriber调用onNext一个方法,例如:

@Override public void onNext(ReturnValue value) {
  view.displayWhatever(value);
}
Run Code Online (Sandbox Code Playgroud)

现在,在我的单元测试中,我想验证当在gatherData()非错误情况下调用该方法时,将调用视图的方法displayWhatever(value).

问题:

有干净的方法吗?

背景:

  • 我正在使用mockito验证交互,当然还有更多
  • Dagger正在注射整个主持人,除了 TheSubscriber

我试过了什么:

  • 注入订阅者并在测试中模拟它.看起来有点脏,因为如果我想改变演示者与服务交互的方式(说不是Rx),那么我需要改变很多测试和代码.
  • 模拟整个服务.这不是那么糟糕,但要求我嘲笑很多方法而且我没有完全达到我想要的.
  • 在互联网上查找,但没有人似乎有一个干净的直接方式这样做

谢谢您的帮助

android mockito rx-java

3
推荐指数
1
解决办法
1987
查看次数

单元测试失败:java.lang.RuntimeException:android.os.Looper 中的方法 getMainLooper 未被模拟

我遇到了一个挑战,当我单独运行它时,我的测试通过了,但当我运行所有测试时失败了,它向我显示了以下错误消息:

java.lang.RuntimeException:android.os.Looper 中的 getMainLooper 方法未被模拟。有关详细信息,请参阅http://g.co/androidstudio/not-mocked

在 android.os.Looper.getMainLooper(Looper.java) 在retrofit2.Platform$Android$MainThreadExecutor.(Platform.java:172) 在retrofit2.Platform$Android.defaultCallbackExecutor(Platform.java:145) 在retrofit2.Retrofit$Builder .build(Retrofit.java:585) 在 com.andela.mrm.notifications.SlackService.getApi(SlackService.kt:26) 在 com.andela.mrm.notifications.SlackServiceTest.getAPI(SlackServiceTest.kt:12) 在太阳。在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)在java.lang.reflect.Method.invoke( Method.java:498) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 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.evaluate(InvokeMethod.java:17) 在 org.junit.runners.ParentRunner.runLeaf(ParentRunner. java:325) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在 org.junit.runners.ParentRunner$3.run( ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner。访问 $000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runners .Suite.runChild(Suite.java:128) 在 org.junit.runners.Suite.runChild(Suite.java:27) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 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(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) )在com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)在com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)在com.intellij.rt.execution。 junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

以下是我要测试的 Retrofit 实例:

class SlackService {

    private var …
Run Code Online (Sandbox Code Playgroud)

java junit android kotlin retrofit2

2
推荐指数
1
解决办法
7400
查看次数

使用PowerMockRunner测试LiveData

我的本地单元测试始终使用LiveData。通常,当您尝试在MutableLiveData上设置值时,会得到

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked.
Run Code Online (Sandbox Code Playgroud)

因为本地JVM无法访问Android框架。我使用以下方法修复了该问题:

@get:Rule
val rule = InstantTaskExecutorRule()
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到我不得不使用PowerMockito模拟来自Google Play库的静态方法。自从我添加

@RunWith(PowerMockRunner::class)
@PrepareForTest(Tasks::class)
Run Code Online (Sandbox Code Playgroud)

在我的测试类声明之上,我开始再次得到这个Looper not模拟错误。我之前在MockitoJUnitRunner中使用了此规则,一切都很好。

android kotlin powermockito android-livedata

1
推荐指数
1
解决办法
557
查看次数