Reputation: 151
I am writing unit test for my service (ClassUnderTest
) class. I am using @Mock
for all the data members.
Now, to test the ClassUnderTest
, I need to create an object for the ClassUnderTest
.
I have two options,
Create a new object for ClassUnderTest
and send the mocks in the constructor.
Or use the @InjectMocks
annotation for the ClassUnderTest
.
I was wondering, are the two approaches same or are their some attentional benefits of using @InjectMocks
?
@Mock
private NodeLaunchWorkflowService nodeLaunchWorkflowService;
@InjectMocks
private NodeLaunchWorkflowController nodeLaunchWorkflowController;
or
@Mock
private NodeLaunchWorkflowService nodeLaunchWorkflowService;
private NodeLaunchWorkflowController nodeLaunchWorkflowController;
@Before
public void setUp() throws JSONException {
MockitoAnnotations.initMocks(this);
nodeLaunchWorkflowController = new NodeLaunchWorkflowController(nodeLaunchWorkflowService)
}
Upvotes: 0
Views: 235
Reputation: 95704
It's quite the opposite: There is some clear advantage to using the constructor pattern rather than @InjectMocks
. In particular, as the @InjectMocks documentation and other articles, there are a wide variety of reasons that Mockito will silently fail to inject mocks. This means that innocent-looking class changes may cause obscure failures in your test, as opposed to the clear compilation failures that a constructor call would cause.
With certain automated refactoring tools, you may even be able to change your class in ways that your test will change correctly and automatically as well; it won't with @InjectMocks, which makes the constructor call reflectively deep within Mockito.
@InjectMocks may be useful for very quick unit test coverage in legacy code, but in new development it's usually much better to structure your components to be easily-testable (with exposed constructor calls, for instance) and then to test them with clear calls.
Upvotes: 1