Testowanie integracyjne przy użyciu mocków Podstawy
Transkrypt
Testowanie integracyjne przy użyciu mocków Podstawy
Testowanie integracyjne przy użyciu mocków Podstawy Michał Borek 21 grudnia 2009 1 Wstęp Podczas testowania integracyjnego często korzystamy z funkcjonalności, które znajdują się w innych pakietach i nie mamy bezpośredniego dostępu do kodu źródłowego tych pakietów. Dodatkowym problemem okazuje się testowanie takich elementów jak: 1. Wysyłanie emaili 2. Przesyłanie plików na serwer (przy pomocy formularza http) Aby poradzić sobie z problemami emulowania powyższych funkcjonalności, stworzone zostały mocki, czyli klasy, które “udają” prawdziwe obiekty, tworzone w kontekście aplikacji podczas uruchamiania jej na serwerze. Z bardzo dużej liczby dostępnych rozwiązań zostało wybrane tylko kilka ciekawych, i sprawdzonych w praktyce. Poniższe przykłady dotyczą szkieletu Spring MVC z wykorzystaniem narzędzia Maven, jednakże niektóre z nich mogą być śmiało stosowane w każdym innym projekcie, niezwiązanym ze Spring Framework. 2 2.1 Wybrane rozwiązania Dumbster - prosty serwer SMTP Dumbster jest prostym fałszywym serwerem SMTP, który idealnie nadaje się do testowania wysyłania emaili w naszych aplikacjach. Dumbster umożliwia sprawdzenie, czy dany email doszedł w wybrane miejsce, a nawet czy treść wysłanego emaila zgadza się z założeniami. 2.1.1 Konfiguracja Aby mieć możliwość korzystania z Dumbstera w naszym projekcie, wystarczy dodać do pliku konfiguracyjnego naszego projektu (pom.xml) następującą zależność: <dependency> <groupId>dumbster</groupId> <artifactId>dumbster</artifactId> 1 <version>1.6</version> <scope>test</scope> </dependency> Innym sposobem na skorzystanie z Dumbstera jest pobranie paczki ze strony projektu: http://sourceforge.net/projects/dumbster/ Serwer nie wymaga żadnej dodatkowej konfiguracji, co jest niewątpliwie dużą zaletą. 2.1.2 Przykład użycia Dumbster oferuje zarówno sprawdzanie liczby emaili, które otrzymał, jak również treści poszczególnych emaili. Przykład upewnienia się, czy dany email doszedł: @Test public void testSendCreateAccountVerification() { SimpleSmtpServer server = SimpleSmtpServer.start(); try { ... emailVerificationServiceImpl.sendVerification(user); ... assertTrue("Message should be sent", server.getReceivedEmailSize() == 1); } finally { server.stop(); } Metoda sendCreateAccountVerification wysyła emaila weryfikacyjnego, do założenia konta. Aby upewnić się, że taki email rzeczywiście jest wysyłany, wystarczy sprawdzić, czy został on odebrany przez serwer smtp, za co odpowiedzialna jest linijka: assertTrue("Message should be sent", server.getReceivedEmailSize() == 1); Aby sprawdzić, czy treść emaila zgadza się z założeniami: Iterator emailIterator = server.getReceivedEmail(); SmtpMessage email = (SmtpMessage)emailIterator.next(); assertTrue(email.getHeaderValue("Subject").equals("Link aktywacyjny")); 2.2 MockMultipartFile - sposób na testowanie przesyłania plików W aplikacjach webowych często potrzebujemy testować klasy, które zajmują się przesyłaniem plików przez formularz umieszczony na stronie webowej. Aby obsłużyć ten formularz często korzystamy z obiektu klasy MultipartFile. Spring udostępnia klasę: MockMultipartFile, zawartą w org.springframework.mock.web, która udaje prawdziwy obiekt MultipartFile. 2 2.2.1 Przykład użycia Aby skorzystać z MockMultipartFile musimy stworzyć obiekt klasy FileInpuStream, który zawiera plik, który wykorzystamy do testów (w naszym przypadku image.jpg). Następnie tworzymy obiekt klasy MockMultipartFile i przypisujemy, podając nazwę pliku, oryginalną nazwę pliku (jeżeli jest inna), typ pliku (opcjonalnie) i wymieniony wyżej obiekt klasy FileInputStream. Po utworzeniu instancji klasy MockMultipartFile możemy korzystać z niej tak jak z instancji prawdziwej klasy MultipartFile. Poniżej znajduje się przykład testu z wykorzystaniem MockMultipartFile: @Test public void testUploadImageAndAddToGame() throws Exception { String fileName = "image.jpg"; try { InputStream is = new FileInputStream("src\\test\\resources\\mock_files\\" + fileName); MockMultipartFile mockMultipartFile = new MockMultipartFile(fileName, fileName, "image/jpeg", is); FileUploadBean file = new FileUploadBean(); file.setFile(mockMultipartFile); fooService.uploadFile(file); File file = new File(filePath + fileName); assertThat("There should be image uploaded", file.exists(), is(true)); } finally { File file = new File(filePath + fileName); if (file.exists()) { file.delete(); } } } 3