Mijn vraag
Op dit moment ben ik in groepsverband bezig met het ontwikkelen van een webapplicatie. Hierbij is het noodzakelijk om een gebruiker zijn e-mailadres te laten verifiëren door middel van een willekeurig gegenereerde token die in de link meegestuurd wordt. Deze token staat gehashed opgeslagen in de database. De methode die mailt naar de gebruiker heet mailTheUser. Deze methode roept voor het versturen van een bericht de abstracte class javax.mail.Transport aan. De methode Transport.send(message) is static. Ik wil de mailTheUser methode graag unittesten, omdat het natuurlijk de line coverage omhoog helpt. Ook wil ik graag verifiëren dat er inderdaad naar het catch gedeelte gegaan wordt, wanneer er een fout optreedt bij de static void methode in Transport. De mailTheUser-methode staat in de MailingServiceImpl class. Deze heeft een interface die hij implementeert. Dit is de service-layer. Alle andere services in de applicatie worden aangeroepen door de controller, maar deze service is daar dus een uitzondering op, omdat hij op meerdere plekken binnen de authenticatie gebruik wordt. Er wordt dus gebruik gemaakt van het REST pattern. Dit testen doe ik met PowerMock, omdat Mockito geen static void methodes kan mocken. Met PowerMock lijkt het te werken, maar dan wordt er wel een exception gethrowed, wanneer ik direct vanuit de test de Transport.send() methode aanroep. Roep ik in de test echter de mailTheUser() methode aan die getest moet worden, dan komt de exception er dus niet aan. Zou iemand weten hoe ik wel op een correcte manier Transport.send() een MessagingException kan laten gooien, wanneer ik hem aanroep in de test vanuit de mailTheUser() methode?
Relevante software en hardware die ik gebruik
JetBrains IntelliJ IDEA Ultimate 2018.3.2
Maven 3.6.0
TomEE Plus 7.1.0
Java EE
Java 8
Wat ik al gevonden of geprobeerd heb
Ik heb geprobeerd om het probleem op te lossen door gebruik te maken van PowerMock. Hierin heb ik aangegeven dat doThrow(new MessagingException("ExampleExceptionMessage") moet gebeuren wanneer de Transport.class aangeroepen wordt. Ook heb ik geprobeerd de MailTheUser() methode de exception niet te laten loggen, maar er voor tijdelijk een RuntimeException op te gooien.
Hieronder staat een voorbeeld van de MailTheUser() methode:
Hieronder bevindt zich de unittest:
En de hierbij behorende Maven dependencies in de pom.xml:
Op dit moment ben ik in groepsverband bezig met het ontwikkelen van een webapplicatie. Hierbij is het noodzakelijk om een gebruiker zijn e-mailadres te laten verifiëren door middel van een willekeurig gegenereerde token die in de link meegestuurd wordt. Deze token staat gehashed opgeslagen in de database. De methode die mailt naar de gebruiker heet mailTheUser. Deze methode roept voor het versturen van een bericht de abstracte class javax.mail.Transport aan. De methode Transport.send(message) is static. Ik wil de mailTheUser methode graag unittesten, omdat het natuurlijk de line coverage omhoog helpt. Ook wil ik graag verifiëren dat er inderdaad naar het catch gedeelte gegaan wordt, wanneer er een fout optreedt bij de static void methode in Transport. De mailTheUser-methode staat in de MailingServiceImpl class. Deze heeft een interface die hij implementeert. Dit is de service-layer. Alle andere services in de applicatie worden aangeroepen door de controller, maar deze service is daar dus een uitzondering op, omdat hij op meerdere plekken binnen de authenticatie gebruik wordt. Er wordt dus gebruik gemaakt van het REST pattern. Dit testen doe ik met PowerMock, omdat Mockito geen static void methodes kan mocken. Met PowerMock lijkt het te werken, maar dan wordt er wel een exception gethrowed, wanneer ik direct vanuit de test de Transport.send() methode aanroep. Roep ik in de test echter de mailTheUser() methode aan die getest moet worden, dan komt de exception er dus niet aan. Zou iemand weten hoe ik wel op een correcte manier Transport.send() een MessagingException kan laten gooien, wanneer ik hem aanroep in de test vanuit de mailTheUser() methode?
Relevante software en hardware die ik gebruik
JetBrains IntelliJ IDEA Ultimate 2018.3.2
Maven 3.6.0
TomEE Plus 7.1.0
Java EE
Java 8
Wat ik al gevonden of geprobeerd heb
Ik heb geprobeerd om het probleem op te lossen door gebruik te maken van PowerMock. Hierin heb ik aangegeven dat doThrow(new MessagingException("ExampleExceptionMessage") moet gebeuren wanneer de Transport.class aangeroepen wordt. Ook heb ik geprobeerd de MailTheUser() methode de exception niet te laten loggen, maar er voor tijdelijk een RuntimeException op te gooien.
Hieronder staat een voorbeeld van de MailTheUser() methode:
Java: MailingServiceImpl.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| public class MailingServiceImpl implements MailingService { private static final Logger LOGGER = Logger.getLogger(MailingService.class.getName()); @Override void mailTheUser(String messageString, Account user, String link, String messageString2) { final String from = "example@example.com"; final String username = "exampleUsername"; final String password = "examplePassword"; String to = user.getEmail(); Properties properties = this.getProperties(); Session session = Session.getInstance(properties, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); message.setSubject("Verifieer uw account"); message.setText(messageString + link + messageString2); Transport.send(message); } catch (MessagingException e) { LOGGER.log(Level.SEVERE, e.toString(), e); } } private Properties getProperties() { String fromHostServer = "smtp.gmail.com"; String smtpPort = "587"; Properties properties = new Properties(); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.smtp.host", fromHostServer); properties.put("mail.smtp.port", smtpPort); return properties; } } |
Hieronder bevindt zich de unittest:
Java: MailingServiceImpl.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| @RunWith(PowerMockRunner.class) @PrepareForTest({MailingServiceImpl.class, Transport.class}) public class MailingServiceImplTest { private MailingServiceImpl sut; @Before public void setUp() { sut = new MailingServiceImpl(); PowerMockito.mockStatic(Transport.class); } @Test public void unitTestOfTheMailingMethodSuccessful() { String messageString = "testString"; String testEmailAddress = "example@example.com"; Account userExample = new Account(testEmailAddress); String link = "dummyLink"; PowerMockito.doNothing().when(Transport.class); sut.mailTheUser(messageString, userExample, link, messageString); } @Test public void unitTestOfTheMailingMethodFailed() { String link = "dummyLink"; String messageString = "testString"; String testEmailAddress = "example@example.com"; PowerMockito.doThrow(new MessagingException("ExceptionExampleText")).when(Transport.class); Account userExample = new Account(testEmailAddress); sut.mailTheUser(messageString, userExample, link, messageString); } } |
En de hierbij behorende Maven dependencies in de pom.xml:
XML: pom.xml
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
| <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> |
[ Voor 2% gewijzigd door daanb14 op 09-01-2019 11:34 . Reden: Gemiste tab gerepareerd. ]