Статьи

JUnit Тестирование приложения Spring MVC: Контроллер тестирования

В продолжение моих предыдущих блогов, посвященных знакомству со Spring MVC и слою службы тестирования в Spring MVC , в этом блоге я продемонстрирую, как тестировать контроллер в Spring MVC . Целью этой демонстрации является двухкратное построение уровня контроллера с использованием TDD и увеличение покрытия кода во время JUnit-тестирования контроллера.

Если вы спешите, получите последний код от Github и выполните команду ниже

mvn clean test -Dtest=com.example.bookstore.web.controller.SpringMvcTestLoginControllerTest

Поскольку в моем предыдущем блоге мы уже протестировали и внедрили уровень обслуживания, в этом блоге нам нужно сосредоточиться только на тестировании контроллера. Для тестирования контроллера я буду использовать фреймворк Spring-Test-MVC , который я достаточно обсуждал в своих предыдущих блогах. Spring-test-MVC реализует домен-специфический язык (DSL) для тестирования контроллера.

В качестве первого шага мы определяем класс LoginControllerTestConfiguration с помощью класса LoginControllerTest. Если вы заметили, что в этом классе определены 2 bean-компонента, и мы пометили его как @Configuration, который показывает, что это класс Spring Context. В тесте JUnit мы использовали класс @Autowired LoginController и класс @Autowired AccountService. При создании Бина в файле конфигурации мы также пометили класс AccountService с помощью Mockito ,

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringMvcTestLoginControllerTest {

@Configuration
static class LoginControllerTestConfiguration {

@Bean
public AccountService accountService() {
return Mockito.mock(AccountService.class);
}

@Bean
public LoginController loginController() {
return new LoginController();
}
}
@Autowired
private LoginController loginController;

@Autowired
private AccountService accountService;
}

В качестве следующего шага давайте настроим данные. Если вы заметили приведенный ниже код, мы также отключили метод входа в AccountService для возврата предварительно сконфигурированных данных с использованием Mockito .

@Before
public void setup() throws Exception {
this.account = new AccountBuilder() {
{
address("Herve", "4650", "Rue de la station", "1", null, "Belgium");
credentials("john", "secret");
name("John", "Doe");
}
}.build(true);

Mockito.when(this.accountService.login("john", "secret")).thenReturn(this.account);
}

Затем мы пишем тест, в котором мы устанавливаем loginController в MockMvcBuilders и используем DSL Spring-test-MVC для вызова уровня контроллера и выполнения утверждений. Теперь, если вы запустите тест, он пройдет успешно.

@Test
public void testHandleLogin() throws Exception {
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(this.loginController).build();
mockMvc.perform(post("/login").param("username", "john").param("password", "secret"))
.andExpect(status().isOk())
.andExpect(request().sessionAttribute(LoginController.ACCOUNT_ATTRIBUTE, this.account))
.andExpect(redirectedUrl("/index.htm"));
}

Наконец, loginController выглядит следующим образом:

@Controller
@RequestMapping(value = "/login")
public class LoginController {

@Autowired
private AccountService accountService;

@RequestMapping(method = RequestMethod.POST)
public String handleLogin(@RequestParam String username, @RequestParam String password, HttpSession session)
throws AuthenticationException {
Account account = this.accountService.login(username, password);
session.setAttribute(ACCOUNT_ATTRIBUTE, account);
String url = (String) session.getAttribute(REQUESTED_URL);
session.removeAttribute(REQUESTED_URL); // Remove the attribute
if (StringUtils.hasText(url) && !url.contains("login")) { // Prevent loops for the login page.
return "redirect:" + url;
} else {
return "redirect:/index.htm";
}
}
}

Я надеюсь, что этот блог помог вам. В моем следующем блоге мы будем реализовывать веб-слой.