2013-03-23 22 views
3

我正在使用Dagger将依赖关系注入到Android项目中的活动中。所有供应商都保存在一个由Application子类存储和管理的模块中。活动注入其依赖项onCreate(),从上下文获取模块。匕首和Android - 测试中的竞争条件?

在测试中,我有时需要交换默认模块为另一个人。我正在使用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()。线程睡眠时间越长,出现故障的几率就越小,但这并不能解决问题。

是什么原因导致这种奇怪的行为,以及如何克服这个问题的任何想法?

+0

你是什么意思时,你说,它失败了呢?它会崩溃吗,你有错误吗,有没有什么有用的logcat? – ZoFreX 2013-10-08 21:24:09

回答

1

我遇到使用匕首和黄瓜,JVM我的测试类似的问题。这里有几个陷阱看出来:

  • 当你设置你的对象图到一个新的,确保有老图表组件没有挥之不去的引用。这意味着任何活动,服务,广播接收器等,它们可能仍然在系统中处于活动状态,并持有对由图形注入的对象的引用。考虑在重置图表之前完成所有打开的活动。在我的情况下,我有一个后台服务,坚持从旧图的注入引用。我必须在服务中明确呼叫stopSelf(),以防止它在测试运行之间停留。这允许它从新图形重新开始时注入。
  • 使用完全随机的ID为PendingIntents,通知,并且采用ID的任何其他部分的Android。我无意中在我的PendingIntents中重新使用了ID,这导致了一些棘手的错误。
  • 查找您重置图形之前,之后可能持续的任何其他国家。我最终想出了一个程序来彻底清除我的应用程序状态并重新开始:清除所有共享首选项,取消所有通知,完成所有打开的活动,然后重置图形。