Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Mock an @Inject Interface

I have this Service Interface

public interface ABC {
    public String getAbc();
}

And I have this controller that uses this Service

public class Do {
    @Inject ABC abc;

    public String doAbc() {
       String a = abc.getAbc();
    }
}

In my Unit test, I want to be able to mock out this ABC and Not have to provide an actual implementation. Here is what works:

public class TestDo {
   @Mock
   private Do do;

   @Mock
   private ABC abc;

   @Before
   public void init() {
       MockitoAnnotations.initMocks(this);
       do.abc = abc;
   }

   @Test
   public void testDo() {
       when(do.doAbc()).thenCallRealMethod();
       do.doAbc();
       assertSomething...
   }
}

But what I do not want to do is do.abc = abc;, from all my searches, in order to do @InjectMock, I need to provide a concrete class. Is there a way for me to use the interface but yet able to Inject the mocked interface into do without the need to exposed my ABC inject in Do Class? I want to make ABC a private variable, and still able to inject an interface through Mockito.

like image 594
Churk Avatar asked Feb 07 '23 18:02

Churk


1 Answers

public interface ABC {
    public String getAbc();
}

public class Do {

    @Inject
    ABC abc;

    public String doAbc() {
        System.out.println("Injected abc is " + (abc == null ? "null" : "not null"));
        return abc.getAbc();
    }

}


public class TestDo {
    @Mock
    private ABC abc;

    @InjectMocks
    private Do ddo;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void simpleTest() {
        System.out.println(ddo.doAbc());
    }

}

output is:

Injected abc is not null
null
like image 83
Rustam Avatar answered Feb 10 '23 10:02

Rustam