使用Dagger 2在App中使用Robolectric进行测试的Android应用程序类

时间:2016-07-06 10:44:07

标签: android unit-testing robolectric dagger-2

在测试方面,我是一个完全的初学者,我当前的任务是修复一个问题,使现有的测试停止运行。

使用Robolectric的几项测试失败并显示错误消息

java.util.ServiceConfigurationError: org.robolectric.internal.ShadowProvider: Provider org.robolectric.Shadows not a subtype
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)

我在this Github帖子中读到,如果环境配置存在问题,可能会发生此错误。经过一些测试后,我可以将问题缩小到Application classinitPicassoinitJobDispatcher中的两个方法,这两个方法初始化Picasso和正在运行的Firebase作业偶尔

public class MyApplication extends Application {

    private ApplicationComponent applicationComponent;

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

        Timber.plant(new Timber.DebugTree());
        AndroidThreeTen.init(this);

        Fabric.with(this, new Crashlytics());
        initPicasso();

        applicationComponent = DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();

        initJobDispatcher();
    }

    void initPicasso() {
        final String PICASSO_CACHE = "picasso-cache";

        File cacheDir = new File(getApplicationContext().getCacheDir(), PICASSO_CACHE);
        if (!cacheDir.exists()) {
            //noinspection ResultOfMethodCallIgnored
            cacheDir.mkdirs();
        }

        Cache cache = new Cache(cacheDir, 50 * 1024 * 1024);

        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Timber.d("XYZ" + message);
            }
        });
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

        OkHttpClient client = new OkHttpClient.Builder()
                .addNetworkInterceptor(httpLoggingInterceptor)
                .cache(cache)
                .build();

        Picasso.setSingletonInstance(
                new Picasso.Builder(this)
                        .listener(new Picasso.Listener() {
                            @Override
                            public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {

                            }
                        })
                        .downloader(new OkHttp3Downloader(client))
                        .build()
        );
    }

    void initJobDispatcher() {
        Driver myDriver = new GooglePlayDriver(this);
        FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(myDriver);

        Timber.d("Setting up Job at: %s", LocalDateTime.now().toString());

        Job job = dispatcher.newJobBuilder()
                .setService(SyncJobService.class)
                .setTag("my-job-tag")
                .setConstraints(Constraint.ON_ANY_NETWORK)
                .setTrigger(Trigger.executionWindow(15, 25))
                .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
                .setRecurring(false)
                .build();

        int result = dispatcher.schedule(job);
        if (result != FirebaseJobDispatcher.SCHEDULE_RESULT_SUCCESS) {
            Timber.e("Job could not be scheduled: %d", result);
        }
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }
}

如果我注释掉这两种方法,那么测试就可以了。

现在我的问题是: 我如何模拟Application class或至少这两种方法? 我尝试创建一个覆盖这些方法的测试Application class,但这并没有帮助。

public class MyApplicationTest extends Application {

    void initPicasso() {
        //do nothing here
        System.out.println("Using the MyApplicationTest application");
    }

    void initJobDispatcher() {
        //do nothing here
    }
}

或者当这个项目使用Dagger2时,有没有办法使用匕首来模拟Application class?由于这个区域对我来说是全新的,所以我们非常感谢任何建议或建议。

0 个答案:

没有答案