В продолжение моих предыдущих блогов о введении в Spring MVC и тестировании уровня DAO в Spring MVC , в этом блоге я продемонстрирую, как тестировать сервисный уровень в Spring MVC . Целью этой демонстрации является двухкратное построение уровня обслуживания с использованием TDD и увеличение покрытия кода во время тестирования уровня обслуживания JUnit.
Если вы спешите, получите последний код от Github и выполните команду ниже
mvn clean test -Dtest=com.example.bookstore.service.AccountServiceTest
Поскольку в моем предыдущем блоге мы уже тестировали уровень DAO, в этом блоге нам нужно сосредоточиться только на тестировании уровня обслуживания. Нам нужно смоделировать уровень DAO, чтобы мы могли контролировать поведение на уровне служб и охватывать различные сценарии. Mockito — это хороший фреймворк, который используется для имитации метода, возврата известных данных и подтверждения этого в JUnit.
В качестве первого шага мы определяем класс AccountServiceTestContextConfiguration с помощью класса AccountServiceTest. Если вы заметили, что в этом классе определены 2 bean-компонента, и мы пометили его как @Configuration, который показывает, что это класс Spring Context. В тесте JUnit мы использовали класс @Autowired AccountService. И AccountServiceImpl @Autowired класс AccountRepository. При создании Бина в файле конфигурации мы также пометили класс AccountRepository с помощью Mockito,
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class AccountServiceTest { @Configuration static class AccountServiceTestContextConfiguration { @Bean public AccountService accountService() { return new AccountServiceImpl(); } @Bean public AccountRepository accountRepository() { return Mockito.mock(AccountRepository.class); } } //We Autowired the AccountService bean so that it is injected from the configuration @Autowired private AccountService accountService; @Autowired private AccountRepository accountRepository;
Во время настройки JUnit мы используем метод mockito mock findByUsername для возврата предопределенного объекта учетной записи, как показано ниже
@Before public void setup() { Account account = new AccountBuilder() { { address("Herve", "4650", "Rue de la gare", "1", null, "Belgium"); credentials("john", "secret"); name("John", "Doe"); } }.build(true); Mockito.when(accountRepository.findByUsername("john")).thenReturn(account); }
Теперь мы пишем тесты, как показано ниже, и тестируем как положительные, так и отрицательные сценарии,
@Test(expected = AuthenticationException.class) public void testLoginFailure() throws AuthenticationException { accountService.login("john", "fail"); } @Test() public void testLoginSuccess() throws AuthenticationException { Account account = accountService.login("john", "secret"); assertEquals("John", account.getFirstName()); assertEquals("Doe", account.getLastName()); } }
Наконец, мы проверяем, что метод findByUsername вызывается только один раз успешно, как показано ниже в разделе
@After public void verify() { Mockito.verify(accountRepository, VerificationModeFactory.times(1)).findByUsername(Mockito.anyString()); // This is allowed here: using container injected mocks Mockito.reset(accountRepository); }
Класс AccountService выглядит следующим образом:
@Service @Transactional(readOnly = true) public class AccountServiceImpl implements AccountService { @Autowired private AccountRepository accountRepository; @Override public Account login(String username, String password) throws AuthenticationException { Account account = this.accountRepository.findByUsername(username, password); } else { throw new AuthenticationException("Wrong username/password", "invalid.username"); } return account; } }
Я надеюсь, что этот блог помог вам. В моем следующем блоге я продемонстрирую, как построить тест JUnit для контроллера.
Ссылка:
Pro Spring MVC: с веб-потоком by Мартен Дейнм, Коен Сернелс