Question

When a class implements an interface all we have to do is mock that interface.

However there are some cases when a class doesn't implement an interface, in that case binding the class to a mock leads guice to get the mocked object dependencies.

To clarify:

class A {
    @Inject B;
}

class B{
   @Inject C;    
}

bind(a.class).toInstance(mock(B.class));

In this scenario, I don't care B's dependencies, but guice stills tries to inject C inside B.

Is there a way to avoid this without defining an interface?

Was it helpful?

Solution

First of all, I strongly recommend against using dependency injection in unit tests. When you're unit testing single class you should create it and pass its dependencies directly, through a constructor or methods. You won't have these problems then.

It's another story when you're writing integration tests though. There are several solutions to your problem.

  1. Make sure all your classes receive dependencies only through injectable constructors. This way Guice won't inject anything because the object will be created by Mockito.

  2. Use providers (and scoping, if needed). The following is equivalent to your attempt sans injection into B (I assume that you really meant bind(B.class).toInstance(mock(B.class)):

    bind(B.class).toProvider(new Provider<B> {
        @Override
        public B get() {
            return mock(B.class);
        }
    }).in(Singleton.class);
    

You should tweak the scope to satisfy your needs.

OTHER TIPS

Using Mockito to partially solve this was quite easy.

You will need to use @Mock and @InjectMocks annotations like this

ATest{
   @Mock B;
   @InjectMocks A;

   public void setUp(){
       MockitoAnnotations.initMocks(this);
   }
}

This way Mockito will do the inject instead of guice, there are a couple of restrictions to successfully inject the mock.

This works pretty well until your code have a strong dependency on a class.

Lets say inside A i have something like C obj = new C(); and C have injected fields.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top