I know there is an indirect answer to that question in other posts here on stackoverflow. For example this:
But I would need the most simple and direct answer to my particular question. Since one thing is still not entirely clear to me. I will give details below.
I am going to use an example from a book of Tomasz Kaczanowski - "Practical Unit testing with JUnit and Mockito"
The example is as follows:
Class to be tested:
public class Messenger {
private TemplateEngine templateEngine;
private MailServer mailServer;
public Messenger(MailServer mailServer, TemplateEngine templateEngine) {
this.mailServer = mailServer;
this.templateEngine = templateEngine;
}
public void sendMessage(Client client, Template template) {
String msgContent = templateEngine.prepareMessage(template, client);
mailServer.send(client.getEmail(), msgContent);
}
}
Test class:
public class MessengerTest {
private static final String CLIENT_EMAIL = "some@email.com";
private static final String MSG_CONTENT = "Dear John! You are fired.";
@Test
public void shouldSendEmail() {
Template template = mock(Template.class);
Client client = mock(Client.class);
MailServer mailServer = mock(MailServer.class);
TemplateEngine templateEngine = mock(TemplateEngine.class);
Messenger sut = new Messenger(mailServer, templateEngine);
when(client.getEmail()).thenReturn(CLIENT_EMAIL);
when(templateEngine.prepareMessage(template, client)).thenReturn(MSG_CONTENT);
sut.sendMessage(client, template);
verify(mailServer).send(CLIENT_EMAIL, MSG_CONTENT);
}
}
(I tried to format the code and make the sytnax highlited, but I don't know how to do it, even though I read some posts on meta.stackoverflow. Would appreciate hints on that as well.)
So my question is: Is the code below with annotations equivalent?
public class MessengerTest {
private static final String CLIENT_EMAIL = "some@email.com";
private static final String MSG_CONTENT = "Dear John! You are fired.";
@Test
public void shouldSendEmail() {
@Mock
Template template;
@Mock
Client client;
@Mock
MailServer mailServer;
@Mock
TemplateEngine templateEngine;
@InjectMocks
Messenger sut;
// given
when(client.getEmail()).thenReturn(CLIENT_EMAIL);
when(templateEngine.prepareMessage(template, client)).thenReturn(MSG_CONTENT);
// when
sut.sendMessage(client, template);
// then
verify(mailServer).send(CLIENT_EMAIL, MSG_CONTENT);
}
}
Are the comments
// given
// when
// then
used properly, as good practice says?
Also, in the mentioned similar question it says, that if I want to use annotations, I need to annotate my test class with: @RunWith(MockitoJUnitRunner.class)
So it is done in the question mentioned. But in my production code I am reading, there is no such annotation, and the tests work. How come? Is that annotation necessary, or not?