Andy Res Andy Res - 2 months ago 13
Java Question

Mocking an injected field in unit tests

I have a

class which uses a field injected through Dagger, it looks something like this:

public class RssListPresenter {

RssService rssService; // <-- injected field

public RssListPresenter() {

private void setupDI() {
.networkModule(new NetworkModule())

public void loadItems() {
Rss rss = rssService.getRssFeed()
// ....

Everything works fine. Now, I would like to unit test the
class. The question is how do I provide a mock
to the presenter?

Ofcourse I can add a new method
setRssService(RssService rssService)
to the presenter and use it to provide the mock from unit tests, but adding this method just for unit tests does not feel right. What would be the correct way to handle this?

For completeness here are the module and component declarations:

@Component(modules = NetworkModule.class)
public interface NetworkComponent {
void inject(RssListPresenter presenter);

public class NetworkModule {

Retrofit provideRetrofit() {
// ...

RssService providePcWorldRssService(Retrofit retrofit) {
return retrofit.create(RssService.class);



Property injection is not amenable for testing. Constructor injection is much better. Refactor your constructor to look like this:

private final RssService rssService;

public RssListPresenter(RssService rssService) {
        this.rssService = rssService;

Now you can test it easily:

RssService mockRssService;

//system under test
RssListPresenter rssListPresenter;

public void setup() {
    mockRssService = Mockito.mock(RssService.class);
    rssListPresenter = new RssListPresenter(mockRssService);

You shouldn't be using DaggerNetworkComponent.inject(this) inside RssListPresenter. Instead you should be configuring dagger so that when it injects members your top-level classes (Activity, Fragment, Service) it can access the object graph and create an instance of your RssPresenter.

To reiterate, Activity, Fragment etc. are valid injection targets. RssListPresenter etc. are injected dependencies. You need to configure the dependency injection framework, dagger, so that it can provide the correct dependencies to inject into the injection targets.

So you will also need to write a @Provides method for RssListPresenter

@Provides provideRssListPresenter(RssService rssService) {
    return new RssListPresenteR(rssService);