Is this a correct way to use Dagger 2 for Android app in unit test to override dependencies with mocks/fakes?

后端 未结 2 942
别跟我提以往
别跟我提以往 2021-02-02 12:55

For \'regular\' Java project overriding the dependencies in the unit tests with mock/fake ones is easy. You have to simply build your Dagger component and give

2条回答
  •  无人共我
    2021-02-02 13:43

    There is a simpler way to do this, even the Dagger 2 docs mention it but they don't make it very obvious. Here's a snippet from the documentation.

    @Provides static Pump providePump(Thermosiphon pump) {
        return pump;
    }
    

    The Thermosiphon implements Pump and wherever a Pump is requested Dagger injects a Thermosiphon.

    Coming back to your example. You can create a Module with a static boolean data member which allows you to dynamically switch between your real and mock test objects, like so.

    @Module
    public class HttpModule {
    
        private static boolean isMockingHttp;
    
        public HttpModule() {}
    
        public static boolean mockHttp(boolean isMockingHttp) {
            HttpModule.isMockingHttp = isMockingHttp;
        }
    
        @Provides
        HttpClient providesHttpClient(OkHttpClient impl, MockHttpClient mockImpl) {
            return HttpModule.isMockingHttp ? mockImpl : impl;
        }
    
    }
    

    HttpClient can be the super class which is extended or an interface which is implemented by OkHttpClient and MockHttpClient. Dagger will automatically construct the required class and inject it's internal dependencies just like Thermosiphon.

    To mock your HttpClient, just call HttpModule.mockHttp(true) before your dependencies are injected in your application code.

    The benefits to this approach are:

    • No need to create separate test components since the mocks are injected at a module level.
    • Application code remains pristine.

提交回复
热议问题