是否可以使用AndroidAnnotations注入模拟测试?

时间:2012-05-05 17:41:04

标签: android unit-testing mocking ioc-container android-annotations

我还没有找到任何关于如何做到这一点的例子。我假设基于这样的例子是不可能的:

@Bean(MyImplementation.class)
MyInterface myInterface;

已经确定要注入的类。

2 个答案:

答案 0 :(得分:8)

johncarl的补充回答:

  • 没有办法告诉AndroidAnnotations您想要注入模拟而不是真实对象,因为它在编译时工作,所以代码必须始终是生产就绪的。

  • 我建议测试生成的活动,与 Robolectric 相辅相成。注释是在代码中添加行为,因此您不应该像没有注释一样对其进行测试。

  • 小心测试您的活动行为,而不是AndroidAnnotations'行为。框架已经有自己的测试来检查注释是否正常工作:)。

  • 您可以让AndroidAnnotations DI发生,然后重新注入模拟的依赖项。这些字段至少具有默认范围,这意味着它们可以从同一个包中访问,因此您必须在与活动相同的包中创建测试。

    MyActivity_ activity = new MyActivity_();
    
    // myInterface gets injected 
    activity.onCreate(null);
    
    // you reinject myInterface
    activity.myInterface = Mockito.mock(MyInterface.class);
    
  • 在AndroidAnnotations中,通过调用MyImplementation_.getInstance_()来注入依赖项。您可以使用PowerMock等工具对运行时字节码进行操作,以使getInstance_() MyImplementation_方法返回模拟。这可能需要一些初步的工作,因为你必须混合PowerMock测试运行器和Robolectric测试运行器。

修改:我根据此问题更新了documentation内容。

答案 1 :(得分:6)

问题是,您是单元测试还是集成测试?

如果你是单元测试,我会建议使用老式方法使用mocks,使用setter并尝试测试Java代码而不涉及依赖注入框架。这将孤立地测试你的课程并避免很多复杂性。

我的意思是:

public class Test{

    ClassInTest inTest;
    MyInterface myInterface;

    @Before
    public void setup(){
         inTest = new ClassInTest();
         //or your favorite mocking frameowrk
         myInterface = EasyMock.createMock(MyInterface.class);  
         inTest.setMyInterface(myInterface);
    }

    @Test
    public void testMethod(){
        //...mocking test code
    }
}

当然,测试Android活动(以及Android的其他扩展)很困难,因为抛出存根和最终类/方法的异常。这是Robolectric派生(并强烈推荐)实例化/遮蔽Android API的地方。

如果您正在进行集成测试,则可能需要采用其他方法。就个人而言,我会尝试不在集成测试期间进行模拟,因为我尝试测试应用程序,因为它将在生产中运行。但是,如果你真的想要模拟,你可以使用类似的单元测试方法,并在你站起来生成的Activity类之后引入一个模拟。值得注意的是,您可以使用Robotium等框架直接在硬件上执行集成测试。

更多问题,我不知道AndroidAnnotations的任何设施专门用于注入Mocks或将Mocks引入应用程序的注入依赖关系树。