web:framework:spring:tests

Ceci est une ancienne révision du document !


Tests Spring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
         
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.github.bonigarcia</groupId>
        <artifactId>webdrivermanager</artifactId>
        <version>5.3.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Tester un composant (Controller, service…)

HelloController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Controller
public class HelloController {
  @Autowired
  private HelloService helloService;
 
  @GetMapping("/hello")
  public @ResponseBody String helloAction() {
    return helloService.getMessage();
  }
 
  @ModelAttribute("message")
  public String getMessage() {
    return helloService.getMessage();
  }
 
  @GetMapping("/hello/view")
  public String helloViewAction() {
    return "hello";
  }
 
  @GetMapping("/auth/hello")
  public @ResponseBody String authHelloAction() {
    return helloService.getAuthMessage();
  }
 
  @GetMapping("/hello/js/{msg}")
  public String helloWithJSAction(@PathVariable String msg) {
    return "helloJs";
  }
}

Mocking :

  • Serveur : MockMvc
  • Service HelloService : MockBean

HelloControllerTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@WebMvcTest(HelloController.class)
@ContextConfiguration(classes = {WebSecurityConfig.class, SpringTestsApplication.class})
class HelloControllerTest {
 
  @MockBean
  private HelloService helloService;
 
  @Autowired
  private MockMvc mockMvc;
 
  @Test
  void helloShouldReturnBonjour() throws Exception {
    // Given
    when(helloService.getMessage()).thenReturn("Bonjour");
    // When
    ResultActions results = this.mockMvc.perform(MockMvcRequestBuilders.get("/hello"));
    // Then
    results.andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(content().string(containsString("Bonjour")));
  }
 
  @Test
  void helloViewShouldReturnBonjour() throws Exception {
    // Given
    when(helloService.getMessage()).thenReturn("Bonjour");
    // When
    ResultActions results = this.mockMvc.perform(MockMvcRequestBuilders.get("/hello/view"));
    // Then
    results.andExpect(view().name("hello")).andExpect(model().attribute("message", "Bonjour"))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(content().string(containsString("Bonjour")));
  }
}

Test d'intégration avec lancement du serveur sur Random port (pour éviter les conflits).

HelloControllerTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class HttpRequestTest {
 
    @LocalServerPort
    private int port;
 
    @Autowired
    private TestRestTemplate restTemplate;
 
    @Test
    void greetingShouldReturnDefaultMessage() throws Exception {
        assertThat(this.restTemplate.getForObject("http://127.0.0.1:" + port + "/",
                String.class)).contains("Hello World!");
    }
}

Mock du serveur web, remplacé par MockMvc :

HelloControllerTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@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("Bob", "Duke");
  }
 
  @AfterEach
  public void tearDown() {
    userService.deleteAll();
  }
 
  @Test
  void getAllShouldReturnAllUsers() throws Exception {
    this.mockMvc.perform(MockMvcRequestBuilders.get("/rest/users"))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(MockMvcResultMatchers.jsonPath("$.size()").value(1))
        .andExpect(MockMvcResultMatchers.jsonPath("$[0].firstname").value("Bob"))
        .andExpect(MockMvcResultMatchers.jsonPath("$[0].lastname").value("Duke"));
  }
}

Mocking :

  • Serveur web (MockMvc)
  • Roles/Users (WithMockUser, WithAnonymousUser)

SecureApplicationTests.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@SpringBootTest
@AutoConfigureMockMvc
class SecureApplicationTests {
 
  @Autowired
  private MockMvc mockMvc;
 
  @Test
  @WithMockUser("admin")
  void authHelloWithAdminShouldReturnAdmin() throws Exception {
    this.mockMvc.perform(get("/auth/hello")).andDo(print()).andExpect(status().isOk())
        .andExpect(content().string(containsString("admin")));
  }
 
  @Test
  @WithAnonymousUser
  void authHelloWithAnonymousUserShouldReturn401() throws Exception {
    this.mockMvc.perform(get("/auth/hello")).andDo(print()).andExpect(status().isUnauthorized());
  }
}

Tests du comportement côté client

SeleniumDemoTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SeleniumDemoTest {
 
  private WebDriver driver;
 
  @LocalServerPort
  int randomServerPort;
 
  String baseUrl;
 
  @SuppressWarnings("deprecation")
  @BeforeEach
  void setUp() throws Exception {
    WebDriverManager.chromedriver().setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--headless");
    driver = new ChromeDriver(options);
    baseUrl = "http://127.0.0.1:" + randomServerPort;
    navigateTo("/hello");
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(120, TimeUnit.MILLISECONDS);
  }
 
  @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, String text) {
    assertTrue(driver.findElement(ByCssSelector.cssSelector(cssSelector)).getText().contains(text));
  }
 
  private void assertElementAttributeContainsText(String cssSelector, String attribute,
      String text) {
    assertTrue(driver.findElement(ByCssSelector.cssSelector(cssSelector)).getAttribute(attribute)
        .contains(text));
  }
 
  public void waitForTextToAppear(String textToAppear, WebElement element, int timeout) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(timeout));
    wait.until(ExpectedConditions.textToBePresentInElement(element, textToAppear));
  }
 
  public void waitForTextToAppear(String textToAppear, WebElement element) {
    waitForTextToAppear(textToAppear, element, 3000);
  }
 
  @Test
  void helloRouteShouldReturnBonjour() {
    assertTrue(driver.getCurrentUrl().contains("hello"));
    assertElementContainsText("body", "Bonjour");
  }
 
  @Test
  void helloWithJsRouteShouldReturnLength() {
    String msg = "Bonjour";
    navigateTo("/hello/js/" + msg);
    assertTrue(driver.getCurrentUrl().contains("/hello/js/" + msg));
    assertElementAttributeContainsText("#msg", "value", msg);
    btnClick("#bt");
    assertElementContainsText("#length", msg.length() + "");
  }
 
}

Intégration de Jacoco :

pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.11</version>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

  • web/framework/spring/tests.1702885000.txt.gz
  • Dernière modification : il y a 16 mois
  • de jcheron