Android Unit Tests with Dagger 2

前端 未结 5 1724
死守一世寂寞
死守一世寂寞 2020-12-13 06:08

I have an Android app that uses Dagger 2 for dependency injection. I am also using the latest gradle build tools that allow a build variant for unit testing and one for inst

5条回答
  •  春和景丽
    2020-12-13 06:38

    You have hit the nail on the head by saying:

    application's Component doesn't have inject methods for my test classes

    So, to get around this problem we can make a test version of your Application class. Then we can have a test version of your module. And to make it all run in a test, we can use Robolectric.

    1) Create the test version of your Application class

    public class TestPipeGameApp extends PipeGameApp {
        private PipeGameModule pipeGameModule;
    
        @Override protected PipeGameModule getPipeGameModule() {
            if (pipeGameModule == null) {
                return super.pipeGameModule();
            }
            return pipeGameModule;
        }
    
        public void setPipeGameModule(PipeGameModule pipeGameModule) {
            this.pipeGameModule = pipeGameModule;
            initComponent();
        }}
    

    2) Your original Application class needs to have initComponent() and pipeGameModule() methods

    public class PipeGameApp extends Application {
        protected void initComponent() {
            DaggerPipeGameComponent.builder()
                .pipeGameModule(getPipeGameModule())
                .build();
        }
    
        protected PipeGameModule pipeGameModule() {
            return new PipeGameModule(this);
        }}
    

    3) Your PipeGameTestModule should extend the production module with a constructor:

    public class PipeGameTestModule extends PipeGameModule {
        public PipeGameTestModule(Application app) {
            super(app);
        }}
    

    4) Now, in your junit test's setup() method, set this test module on your test app:

    @Before
    public void setup() {
        TestPipeGameApp app = (TestPipeGameApp) RuntimeEnvironment.application;
        PipeGameTestModule module = new PipeGameTestModule(app);
        app.setPipeGameModule(module);
    }
    

    Now you can customize your test module how you originally wanted.

提交回复
热议问题