Différences
Ci-dessous, les différences entre deux révisions de la page.
| Prochaine révision | Révision précédente | ||
| web:framework:spring:tests [2023/12/18 01:13] – créée jcheron | web:framework:spring:tests [2023/12/18 08:45] (Version actuelle) – [Autorisations] jcheron | ||
|---|---|---|---|
| Ligne 28: | Ligne 28: | ||
| < | < | ||
| < | < | ||
| - | < | + | < |
| < | < | ||
| </ | </ | ||
| </ | </ | ||
| + | </ | ||
| + | |||
| + | ===== @WebMvcTest ===== | ||
| + | Tester un composant (Controller, | ||
| + | |||
| + | ==== Controller ==== | ||
| + | <sxh java; | ||
| + | @Controller | ||
| + | public class HelloController { | ||
| + | @Autowired | ||
| + | private HelloService helloService; | ||
| + | |||
| + | @GetMapping("/ | ||
| + | public @ResponseBody String helloAction() { | ||
| + | return helloService.getMessage(); | ||
| + | } | ||
| + | |||
| + | @ModelAttribute(" | ||
| + | public String getMessage() { | ||
| + | return helloService.getMessage(); | ||
| + | } | ||
| + | |||
| + | @GetMapping("/ | ||
| + | public String helloViewAction() { | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | @GetMapping("/ | ||
| + | public @ResponseBody String authHelloAction() { | ||
| + | return helloService.getAuthMessage(); | ||
| + | } | ||
| + | |||
| + | @GetMapping("/ | ||
| + | public String helloWithJSAction(@PathVariable String msg) { | ||
| + | return " | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | ==== Test ==== | ||
| + | |||
| + | Mocking : | ||
| + | * Serveur : <wrap round box> | ||
| + | * Service HelloService : <wrap round box> | ||
| + | |||
| + | |||
| + | <sxh java; | ||
| + | @WebMvcTest(HelloController.class) | ||
| + | @ContextConfiguration(classes = {WebSecurityConfig.class, | ||
| + | class HelloControllerTest { | ||
| + | |||
| + | @MockBean | ||
| + | private HelloService helloService; | ||
| + | |||
| + | @Autowired | ||
| + | private MockMvc mockMvc; | ||
| + | |||
| + | @Test | ||
| + | void helloShouldReturnBonjour() throws Exception { | ||
| + | // Given | ||
| + | when(helloService.getMessage()).thenReturn(" | ||
| + | // When | ||
| + | ResultActions results = this.mockMvc.perform(MockMvcRequestBuilders.get("/ | ||
| + | // Then | ||
| + | results.andExpect(MockMvcResultMatchers.status().isOk()) | ||
| + | .andExpect(content().string(containsString(" | ||
| + | } | ||
| + | |||
| + | @Test | ||
| + | void helloViewShouldReturnBonjour() throws Exception { | ||
| + | // Given | ||
| + | when(helloService.getMessage()).thenReturn(" | ||
| + | // When | ||
| + | ResultActions results = this.mockMvc.perform(MockMvcRequestBuilders.get("/ | ||
| + | // Then | ||
| + | results.andExpect(view().name(" | ||
| + | .andExpect(MockMvcResultMatchers.status().isOk()) | ||
| + | .andExpect(content().string(containsString(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Tests d' | ||
| + | |||
| + | Test d' | ||
| + | |||
| + | <sxh java; | ||
| + | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | ||
| + | class HttpRequestTest { | ||
| + | |||
| + | @LocalServerPort | ||
| + | private int port; | ||
| + | |||
| + | @Autowired | ||
| + | private TestRestTemplate restTemplate; | ||
| + | |||
| + | @Test | ||
| + | void greetingShouldReturnDefaultMessage() throws Exception { | ||
| + | assertThat(this.restTemplate.getForObject(" | ||
| + | String.class)).contains(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== @SpringBootTest & @AutoConfigureMockMvc ==== | ||
| + | |||
| + | Mock du serveur web, remplacé par **MockMvc** : | ||
| + | |||
| + | <sxh java; | ||
| + | @SpringBootTest | ||
| + | @AutoConfigureMockMvc | ||
| + | @AutoConfigureTestDatabase(replace = Replace.NONE) | ||
| + | class RestUserControllerTest { | ||
| + | |||
| + | @Autowired | ||
| + | private MockMvc mockMvc; | ||
| + | |||
| + | @Autowired | ||
| + | private UserService userService; | ||
| + | |||
| + | private static User testUser; | ||
| + | |||
| + | |||
| + | @BeforeEach | ||
| + | public void setup() { | ||
| + | testUser = userService.createUser(" | ||
| + | } | ||
| + | |||
| + | @AfterEach | ||
| + | public void tearDown() { | ||
| + | userService.deleteAll(); | ||
| + | } | ||
| + | |||
| + | @Test | ||
| + | void getAllShouldReturnAllUsers() throws Exception { | ||
| + | this.mockMvc.perform(MockMvcRequestBuilders.get("/ | ||
| + | .andExpect(MockMvcResultMatchers.status().isOk()) | ||
| + | .andExpect(MockMvcResultMatchers.jsonPath(" | ||
| + | .andExpect(MockMvcResultMatchers.jsonPath(" | ||
| + | .andExpect(MockMvcResultMatchers.jsonPath(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | ===== Test sécurité ===== | ||
| + | |||
| + | ==== Authentification ==== | ||
| + | |||
| + | |||
| + | ==== Autorisations ==== | ||
| + | |||
| + | Mocking : | ||
| + | |||
| + | * Serveur web <wrap round box> | ||
| + | * Roles/Users <wrap round box> | ||
| + | |||
| + | <sxh java; | ||
| + | |||
| + | @SpringBootTest | ||
| + | @AutoConfigureMockMvc | ||
| + | class SecureApplicationTests { | ||
| + | |||
| + | @Autowired | ||
| + | private MockMvc mockMvc; | ||
| + | |||
| + | @Test | ||
| + | @WithMockUser(" | ||
| + | void authHelloWithAdminShouldReturnAdmin() throws Exception { | ||
| + | this.mockMvc.perform(get("/ | ||
| + | .andExpect(content().string(containsString(" | ||
| + | } | ||
| + | |||
| + | @Test | ||
| + | @WithAnonymousUser | ||
| + | void authHelloWithAnonymousUserShouldReturn401() throws Exception { | ||
| + | this.mockMvc.perform(get("/ | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Selenium tests ===== | ||
| + | Tests du comportement côté client | ||
| + | |||
| + | <sxh java; | ||
| + | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | ||
| + | class SeleniumDemoTest { | ||
| + | |||
| + | private WebDriver driver; | ||
| + | |||
| + | @LocalServerPort | ||
| + | int randomServerPort; | ||
| + | |||
| + | String baseUrl; | ||
| + | |||
| + | @SuppressWarnings(" | ||
| + | @BeforeEach | ||
| + | void setUp() throws Exception { | ||
| + | WebDriverManager.chromedriver().setup(); | ||
| + | ChromeOptions options = new ChromeOptions(); | ||
| + | options.addArguments(" | ||
| + | options.addArguments(" | ||
| + | options.addArguments(" | ||
| + | driver = new ChromeDriver(options); | ||
| + | baseUrl = " | ||
| + | navigateTo("/ | ||
| + | driver.manage().window().maximize(); | ||
| + | driver.manage().timeouts().implicitlyWait(120, | ||
| + | } | ||
| + | |||
| + | @AfterEach | ||
| + | void tearDown() throws Exception { | ||
| + | if (driver != null) { | ||
| + | driver.quit(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | private void navigateTo(String relativeURL) { | ||
| + | driver.navigate().to(baseUrl + relativeURL); | ||
| + | } | ||
| + | |||
| + | private void fillElement(String name, String content) { | ||
| + | WebElement elm = driver.findElement(By.name(name)); | ||
| + | elm.sendKeys(content); | ||
| + | } | ||
| + | |||
| + | private void btnClick(String cssSelector) { | ||
| + | driver.findElement(ByCssSelector.cssSelector(cssSelector)).click(); | ||
| + | } | ||
| + | |||
| + | private void assertElementContainsText(String cssSelector, | ||
| + | assertTrue(driver.findElement(ByCssSelector.cssSelector(cssSelector)).getText().contains(text)); | ||
| + | } | ||
| + | |||
| + | private void assertElementAttributeContainsText(String cssSelector, | ||
| + | String text) { | ||
| + | assertTrue(driver.findElement(ByCssSelector.cssSelector(cssSelector)).getAttribute(attribute) | ||
| + | .contains(text)); | ||
| + | } | ||
| + | |||
| + | public void waitForTextToAppear(String textToAppear, | ||
| + | WebDriverWait wait = new WebDriverWait(driver, | ||
| + | wait.until(ExpectedConditions.textToBePresentInElement(element, | ||
| + | } | ||
| + | |||
| + | public void waitForTextToAppear(String textToAppear, | ||
| + | waitForTextToAppear(textToAppear, | ||
| + | } | ||
| + | |||
| + | @Test | ||
| + | void helloRouteShouldReturnBonjour() { | ||
| + | assertTrue(driver.getCurrentUrl().contains(" | ||
| + | assertElementContainsText(" | ||
| + | } | ||
| + | |||
| + | @Test | ||
| + | void helloWithJsRouteShouldReturnLength() { | ||
| + | String msg = " | ||
| + | navigateTo("/ | ||
| + | assertTrue(driver.getCurrentUrl().contains("/ | ||
| + | assertElementAttributeContainsText("# | ||
| + | btnClick("# | ||
| + | assertElementContainsText("# | ||
| + | } | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Couverture ===== | ||
| + | Intégration de **Jacoco** : | ||
| + | <sxh xml; | ||
| + | < | ||
| + | < | ||
| + | ... | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| </ | </ | ||