Junit to test a Class with Constructor Injection.

@InjectMocks doesn’t work to test a class with Constructor Injection.

Lets see the class to test:

@Component
public class MyService {

private final MyDependency myFirstDependency;
private final MyDependency mySecondDependency;

MyService(@Qualifier("MyFirstDependencyBean") final MyDependency myFirstDependency,
@Qualifier("MySecondDependencyBean") final MyDependency mySecondDependency){
this.myFirstDependency = myFirstDependency;
this.mySecondDependency = mySecondDependency;
}

public String myOperation(){
if(myFirstDependency.toString().contains("First")){
System.out.println("First Bean available");
return "First";
}
if(mySecondDependency.toString().contains("Second")){
System.out.println("Second Bean available");
return "Second";
}
return "None";
}

}

Junit that will fail with @InjectMocks is provided below. The Junits will fail randomly and Mockito when will not be applied properly.

@RunWith(SpringRunner.class)
public class MyServiceTest {

@Mock
private MyDependency myFirstDependency;

@Mock
private MyDependency mySecondDependency;

@InjectMocks
MyService myService;

@Test
public void testMyOperationFirstBean(){
Mockito.when(myFirstDependency.toString()).thenReturn("First");
Assert.assertEquals("First", myService.myOperation());
}

@Test
public void testMyOperationSecondBean(){
Mockito.when(myFirstDependency.toString()).thenReturn("Second");
Mockito.when(mySecondDependency.toString()).thenReturn("Second");
Assert.assertEquals("Second", myService.myOperation());
}
}

Fix:

The fix is to not use @InjectMocks but to use the myService Constructor as shown below.

   MyService myService;

    @Before
    public void Setup(){
        myService = new MyService(myFirstDependency, mySecondDependency);
    }

The full Junit class is provided below.

@RunWith(SpringRunner.class)
public class MyServiceTest {

    @Mock
    private MyDependency myFirstDependency;

    @Mock
    private MyDependency mySecondDependency;

    MyService myService;

    @Before
    public void Setup(){
        myService = new MyService(myFirstDependency, mySecondDependency);
    }

    @Test
    public void testMyOperationFirstBean(){
        Mockito.when(myFirstDependency.toString()).thenReturn("First");
        Assert.assertEquals("First", myService.myOperation());
    }

    @Test
    public void testMyOperationSecondBean(){
        Mockito.when(myFirstDependency.toString()).thenReturn("Second");
        Mockito.when(mySecondDependency.toString()).thenReturn("Second");
        Assert.assertEquals("Second", myService.myOperation());
    }

}
%d bloggers like this: