How do you override a module/dependency in a unit test with Dagger 2.0?

后端 未结 8 2465
一个人的身影
一个人的身影 2020-11-30 19:13

I have a simple Android activity with a single dependency. I inject the dependency into the activity\'s onCreate like this:

Dagger_HelloComponen         


        
8条回答
  •  半阙折子戏
    2020-11-30 19:50

    THIS ANSWER IS OBSOLETE. READ BELOW IN EDIT.

    Disappointingly enough, you cannot extend from a Module, or you'll get the following compilation error:

    Error:(24, 21) error: @Provides methods may not override another method.
    Overrides: Provides 
        retrofit.Endpoint hu.mycompany.injection.modules.application.domain.networking.EndpointModule.mySe‌​rverEndpoint()
    

    Meaning you can't just extend a "mock module" and replace your original module. Nope, it's not that easy. And considering you design your components in such a way that it directly binds the Modules by class, you can't really just make a "TestComponent" either, because that'd mean you have to reinvent everything from scratch, and you'd have to make a component for every variation! Clearly that is not an option.

    So on the smaller scale, what I ended up doing is making a "provider" that I give to the module, which determines whether I select the mock or the production type.

    public interface EndpointProvider {
        Endpoint serverEndpoint();
    }
    
    public class ProdEndpointProvider implements EndpointProvider {
    
        @Override
        public Endpoint serverEndpoint() {
            return new ServerEndpoint();
        }
    }
    
    
    public class TestEndpointProvider implements EndpointProvider {
        @Override
        public Endpoint serverEndpoint() {
            return new TestServerEndpoint();
        }
    }
    
    @Module
    public class EndpointModule {
        private Endpoint serverEndpoint;
    
        private EndpointProvider endpointProvider;
    
        public EndpointModule(EndpointProvider endpointProvider) {
            this.endpointProvider = endpointProvider;
        }
    
        @Named("server")
        @Provides
        public Endpoint serverEndpoint() {
            return endpointProvider.serverEndpoint();
        }
    }
    

    EDIT: Apparently as the error message says, you CAN'T override another method using a @Provides annotated method, but that doesn't mean you can't override an @Provides annotated method :(

    All that magic was for naught! You can just extend a Module without putting @Provides on the method and it works... Refer to @vaughandroid 's answer.

提交回复
热议问题