如何测试需要授权的屏幕?浓缩咖啡 + MockWebServer

How to test screens which requires authorization? Espresso + MockWebServer

我正在创建 UI 测试。为了不和真正的服务器交互,我使用了MockWebServer。我的目标是模拟各种服务器响应并查看整个程序将如何响应它们。目前,我不明白如何打开需要授权的屏幕。当然,我可以写一个代码,登录到授权屏幕,然后去想要的window。但这需要额外的时间来完成测试,我想避免这种情况。我不想模拟 classes,因为我需要检查应用程序的生产版本。我该怎么做?

对于 DI,我使用 Dagger-2。这是组件代码:

@Singleton
@Component(modules = {
        AvatarsModule.class,
        EncryptionModule.class,
        ApiModule.class,
        WalletsModule.class,
        GeneralModule.class,
        InteractorsModule.class,
        PushNotificationsModule.class,
        AppModule.class
})
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder context(Context context);
        AppComponent build();
    }

    void inject(App app);
}

这是存储授权状态的 class 代码:

public class ApiWrapper {
    private Api api;
    private KeyPair keyPair;
    private Account account; 

    ...

    public Flowable<Authorization> authorize(KeyPair tempKeyPair) {
        return api
                .authorize(tempKeyPair.getPublicKeyString().toLowerCase())
                .subscribeOn(Schedulers.io())
                .doOnNext((authorization -> {
                    this.account = authorization.getAccount();
                    this.keyPair = tempKeyPair;
                }));
    }
    ...
}

如果还有人感兴趣。我写了一个 InstrumentationTestFacade class,其中我使用 Dagger 放置了一个 ApiWrapper 对象。接下来,将 InstrumentationTestFacade 注入到 Application 对象中。由于应用程序对象不是单例,因此主要代码中没有责任泄漏,但是从测试代码中您可以使用以下代码访问此外观:

Application application = (Application) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
InstrumentationTestFacade facade = application.getInstrumentationTestFacade();

下面是一个例子:

public class InstrumentationTestFacade {
    private LogoutInteractor logoutInteractor;
    private SecurityInteractor securityInteractor;
    private ApiWrapper apiWrapper;

    public InstrumentationTestFacade(
            LogoutInteractor logoutInteractor,
            SecurityInteractor securityInteractor,
            ApiWrapper apiWrapper
    ) {
        this.logoutInteractor = logoutInteractor;
        this.securityInteractor = securityInteractor;
        this.apiWrapper = apiWrapper;
    }

    public void logout() {
        logoutInteractor.logout();
    }

    public ApiWrapper getApiWrapper() {
        return apiWrapper;
    }

    public SecurityInteractor getSecurityInteractor() {
        return this.securityInteractor;
    }
}
public class Application extends MultiDexApplication implements HasActivityInjector, HasServiceInjector {

    ...

    @Inject
    InstrumentationTestFacade instrumentationTestFacade;


    @Override
    public void onCreate() {
        super.onCreate();

        DaggerAppComponent
                .builder()
                .context(this)
                .build()
                .inject(this);

    }

    ...

    public InstrumentationTestFacade getInstrumentationTestFacade() {
        return instrumentationTestFacade;
    }
}