Vid automatiserad testning är s.k. test doubles ett viktigt verktyg. Här presenteras olika typer av sådana med exempel på hur de kan implementeras.
Talare är Niklas Lindholm från Appear Networks
10. Ibland är det lättare att själv implementera en test double än att använda ett verktyg.
11. Ibland är det lättare att inte använda test doubles alls utan använda de riktiga beroendena.
12.
13. Man verifierar inte att stuben verkligen blev anropad. Det man verifierar är att klassen man testar gör rätt saker med den data den får från stuben. (S.k. ”state based testing”)
14. Egen stub-implementation @Test public void getMailAdressesForGroup_groupWithUsers_returnsList() throws Exception { UserNotifier userNotifier = new UserNotifier( new UserDbStub(), null ); List<String> adresses = userNotifier.getMailAdressesForGroup( "agroup" ); assertEquals ( "Wrong addresses" , Arrays. asList ( "joe@foo.com" , "bob@bar.org" ), adresses); } private static class UserDbStub implements UserDb { public List<User> getUsersInGroup(String groupName) { return "agroup" .equals(groupName) ? Arrays. asList ( new User( "joe" , "joe@foo.com" ), new User( "bob" , "bob@bar.org" )) : Collections.<User> emptyList (); } }
15. Stub med Mockito @RunWith (MockitoJUnitRunner. class ) public class UserNotifierMockitoTests { @Mock private UserDb userDbStub ; @Test public void getMailAdressesForGroup_groupWithUsers_returnsList() throws Exception { when ( userDbStub .getUsersInGroup( "agroup" )).thenReturn(Arrays. asList ( new User( "joe" , "joe@foo.com" ), new User( "bob" , "bob@bar.org" ))); UserNotifier userNotifier = new UserNotifier( userDbStub , null ); List<String> adresses = userNotifier.getMailAdressesForGroup( "agroup" ); assertEquals ( "Wrong addresses" , Arrays. asList ( "joe@foo.com" , "bob@bar.org" ), adresses); }
16.
17.
18. En mock vet i förväg hur den ska bli anropad så att den kan generera ett fel direkt när det inte stämmer. Enligt xunitpatterns.com:
19. Egen spy-implementation @Test public void greetUser_validUserName_sendsEmail() { MailSenderSpy mailSenderSpy = new MailSenderSpy(); UserNotifier userNotifier = new UserNotifier( new UserDbStub(), mailSenderSpy); userNotifier.greetUser( "joe" ); assertEquals ( "Wrong email address" , " [email_address] " , mailSenderSpy.getEmailAdress()); } private static class MailSenderSpy implements MailSender { private String emailAdress ; public void sendEmail(String emailAdress) { this . emailAdress = emailAdress; } public String getEmailAdress() { return emailAdress ; } }
20. Mock med Mockito @RunWith (MockitoJUnitRunner. class ) public class UserNotifierMockitoTests { @Mock private UserDb userDbStub ; @Mock private MailSender mailSenderMock ; @Test public void greetUser_validUserName_sendsEmail() throws Exception { when ( userDbStub .getUser( "joe" )).thenReturn( new User( "joe" , "joe@foo.com" )); UserNotifier userNotifier = new UserNotifier( userDbStub , mailSenderMock ); userNotifier.greetUser( "joe" ); verify ( mailSenderMock ).sendEmail( "joe@foo.com" ); } }
21.
22. Då man inte verifierar interaktionen med en fake kan man se den som en smartare stub.
23. Fake public class MailSenderFake implements MailSender { public void sendEmail(String emailAdress) throws MailSenderException { if (!emailAdress.matches( "[^@]+@[^@]+" )) { throw new InvalidAddressException( "Bad email address: " + emailAdress); } if (emailAdress.endsWith( ".error" )) { throw new CanNotSendMailException( "Failed sending mail to address: " + emailAdress); } } }
24.
25. Den används bara tex som inparameter eller för att verifiera att samma objekt skickas vidare till ett annat beroende.