Reputation: 1590
Environment :
Spring MVC 4
Junit
Mockito
Code :
Spring Service under test :
@Service("abhishekService")
public class AbhishekServiceImpl implements AbhisheskService {
@Autowired
private DaoOne daoOne;
@Autowired
private DaoTwo daoTwo;
@Autowired
private DaoThree daoThree;
@Autowired
private DaoFour daoThree;
}
Junit Test :
public class AbhishekServiceImplTest {
@Mock
private DaoOne daoOne;
@Mock
private DaoTwo daoTwo;
@Mock
private DaoThree daoThree;
@Mock
private UserDao userDao;
private AbhisheskService abhisheskService;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
abhisheskService = new AbhishekServiceImpl();
}
}
Issue :
1)As shown in code snippet one , the class under test uses four dependencies.
2)As shown in code snippet two , in junit test case class , all 4 dependencies are mocked using @Mock
3)My question is : how these four mocked objects should be injected into test class ?
4)My class under test doesn't have constructor/setter injection but field injection using @Autowired.
5)I don't want to use @InjectMocks
annotation due to its dangerous behavior
as mentioned here
Can anybody please guide on this ?
Upvotes: 1
Views: 612
Reputation: 713
You are trying to test a class wrongly designed to test the behavior i.e. the properties are not accessible to be mocked. AbhishekServiceImpl
has to provide a way to inject the mocks to the class. If you cannot access the fields then it is a clear case of wrongly designed class. Considering that the AbhishekServiceImpl
is a class in a legacy code and you are trying to test the behaviour then you can use reflection to inject the mock objects as below:
DaoOne mockedDaoOne = mock(DaoOne.class);
when(mockedDaoOne.doSomething()).thenReturn("Mocked behaviour");
AbhishekService abhishekService = new AbhishekServiceImpl();
Field privateField = PrivateObject.class.getDeclaredField("daoOne");
privateField.setAccessible(true);
privateField.set(abhishekService, mockedDaoOne);
assertEquals("Mocked behaviour", abhishekService.doSomething());
Its very rare that you test behaviour of a class that you have not written yourself. Though I can imagine a use case where you have to test an external library because its author did not test it.
Upvotes: 2
Reputation: 906
You can mark the junit test with @RunWith(SpringJUnit4ClassRunner.class) and then use @ContextConfiguration to define a context which instantiates the DAOs and service and wires them together.
Upvotes: 0