3

我正在使用 Dagger 将依赖项注入到 Android 项目中的活动中。所有提供者都保存在一个模块中,该模块由Application子类存储和管理。活动将它们的依赖项注入onCreate(),从上下文中获取模块。

在测试中,我有时需要将默认模块换成另一个。我正在使用ActivityAndroidTestCase2. 我在调用之前获取应用程序上下文getActivity(),然后替换模块,如下所示:

Context applicationContext = getInstrumentation()
    .getTargetContext().getApplicationContext();
module.setAppContext(applicationContext);
Thread.sleep(1000);         // note this
((ObjectGraphProvider) applicationContext).setModule(module);

MyApplication代码:

public class MyApp extends Application implements ObjectGraphProvider {

    private ObjectGraph objectGraph;
    private Object module;

    public MyApp() {
        super();
        ApplicationContextModule myModule = new DefaultModule();
        myModule.setAppContext(this);
        this.module = myModule;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        objectGraph = ObjectGraph.create(module);
    }

    @Override
    public ObjectGraph objectGraph() {
        return objectGraph;
    }

    /* Test only */
    public void setModule(Object module) {
        this.module = module;
        objectGraph = ObjectGraph.create(module);
    }
}

可悲的是,测试有时会失败——这就是sleep()第一个代码片段中出现的原因。线程休眠的时间越长,失败的机会就越小,但它并不能永远解决问题。

关于导致这种奇怪行为的原因以及如何解决这个问题的任何想法?

4

1 回答 1

1

我在使用 Dagger 和 Cucumber-jvm 的测试中遇到了类似的问题。以下是一些需要注意的问题:

  • 当您将对象图设置为新对象图时,请确保在旧图中没有对组件的延迟引用。这意味着任何活动、服务、广播接收器等可能在系统中仍然处于活动状态并持有对由图形注入的对象的引用。考虑在重置图表之前完成所有打开的活动。就我而言,我有一个后台服务,它一直使用旧图表中的注入引用。我必须明确调用stopSelf()服务以防止它在测试运行之间停留。这允许它在重新启动时从新图表中获得注入。
  • 对 PendingIntents、Notifications 和任何其他需要 ID 的 Android 部分使用完全随机的 ID。我不小心在我的 PendingIntents 中重新使用了 ID,这导致了一些棘手的错误。
  • 寻找在您重置图表之前和之后可能持续存在的任何其他状态。我最终想出了一个程序来完全清除我的应用程序状态并重新开始:清除所有共享首选项,取消所有通知,完成所有打开的活动,然后重置图表。
于 2014-08-23T13:43:57.910 回答