Reputation: 6893
I am trying to use @Mock to inject two different objects into my class under test. I need them to be two different objects so that I can use when
on each one to produce different results. Everything I've searched on SO points toward this working, but when running the test below - both objects are the same mock.
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import com.ihm.pp.test.UnitTest;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/**
* @author Josh Johnston
*/
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class ConstructorInjectionBug {
@Mock
private IBroken aBroken;
@Mock
private IBroken bBroken;
@InjectMocks
private UsesBroken usesBroken;
@Test
public void testBrokenConstructorInjection() {
when(bBroken.getNumber()).thenReturn(2);
assertEquals(2, usesBroken.getbBroken().getNumber());
when(aBroken.getNumber()).thenReturn(1);
assertEquals(1, usesBroken.getaBroken().getNumber());
}
}
interface IBroken {
int getNumber();
}
class UsesBroken {
private IBroken aBroken;
private IBroken bBroken;
public UsesBroken(IBroken aBroken, IBroken bBroken) {
this.aBroken = aBroken;
this.bBroken = bBroken;
}
public IBroken getaBroken() {
return aBroken;
}
public IBroken getbBroken() {
return bBroken;
}
}
Result:
java.lang.AssertionError:
Expected :1
Actual :2
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at ConstructorInjectionBug.testBrokenConstructorInjection(ConstructorInjectionBug.java:37)
Upvotes: 5
Views: 2811
Reputation: 247163
@InjectMocks
wont know which IBroken
to inject. So it is not that it is broken but more the design is flawed.
You would need to explicitly inject the mocks into the subject under test to get the desired behavior.
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class ConstructorInjectionBug {
@Mock
private IBroken aBroken;
@Mock
private IBroken bBroken;
private UsesBroken usesBroken;
@Test
public void testBrokenConstructorInjection() {
//Arrange
usesBroken = new UsesBroken(aBroken, bBroken);
when(bBroken.getNumber()).thenReturn(2);
when(aBroken.getNumber()).thenReturn(1);
//Act & Assert
assertEquals(2, usesBroken.getbBroken().getNumber());
assertEquals(1, usesBroken.getaBroken().getNumber());
}
}
Upvotes: 6