匕首& Android - 测试中的竞争条件?

时间:2013-03-23 22:39:55

标签: android android-testing dagger

我正在使用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()的原因。线程休眠的时间越长,失败的可能性就越小,但它并没有解决问题。

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

1 个答案:

答案 0 :(得分:1)

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

  • 将对象图设置为新对象时,请确保旧图中没有对组件的延迟引用。这意味着任何活动,服务,BroadcastReceivers等,可能仍然在系统中处于活动状态并保持对图形注入的对象的引用。在重置图表之前,请考虑完成所有打开的活动。在我的情况下,我有一个后台服务,坚持使用旧图表中的注入引用。我必须在服务中明确调用stopSelf()以防止它在测试运行之间停留。这允许它在重新开始时从新图表中进行注入。
  • 为PendingIntents,Notifications以及采用ID的Android的任何其他部分使用完全随机的ID。我不小心在我的PendingIntents中重复使用了ID,这导致了一些棘手的错误。
  • 查找在重置图表之前和之后可能存在的任何其他状态。我最终想出了一个完全清除我的应用状态并重新开始的程序:清除所有共享首选项,取消所有通知,完成所有已打开的活动,然后重置图表。