Search code examples
javamockitoguice

How to mock an object with Guice @Inject?


I have a class A and a class B.

public class A{
    @Inject // Guice Inject
    private B b;
}

The test class looks like -

public class ATest{
    private B b;
    
    private A a;

    @Before
    public void setup() {
        b = Mockito.mock(b.class);
        a = new A();
    }
}

The thing is that class B isn't getting mocked. In the test class, there's a NullPointerException whenever a method of B is getting invoked. I can't make changes to class A. Please help me out on how to mock class B successfully?


Solution

  • I assume that in your case it's not that B isn't mocked, but that it is not injected into a.

    One way to have it injected would be to create a Guice Injector in the test with a Module, which would bind a Class to be injected, B in your case, to a concrete instance of B, and then use Injector#injectMembers(a) to have b injected into a.

    Working example:

    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.mockito.Mockito;
    
    import com.google.inject.AbstractModule;
    import com.google.inject.Guice;
    import com.google.inject.Inject;
    import com.google.inject.Injector;
    
    class InjectableTest {
      private static class Service {
        @Inject
        private Object obj;
    
        public Object getObj() {
          return obj;
        }
      }
    
      private final Object obj = Mockito.mock(Object.class);
      private final Injector injector = Guice.createInjector(new AbstractModule() {
        @Override
        protected void configure() {
          bind(Object.class).toInstance(obj);
        }
      });
    
      @Test
      void t() {
        Service s = new Service();
        injector.injectMembers(s);
        Assertions.assertEquals(obj, s.getObj());
      }
    }
    

    If you need to do it more often than only for one test, have a look at the answers of this question, which discuss different ways of Guice dependency injection in unit tests.