Я написал следующий простой тестовый пример для тестирования MockMvc и WebDriver:
@RunWith(SpringRunner.class)
@WebAppConfiguration("/src/main/resources")
@ContextConfiguration(classes = {MvcConfig.class})
public class exampleTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
private WebDriver driver;
@Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
this.driver = MockMvcHtmlUnitDriverBuilder.webAppContextSetup(this.context).build();
}
@Test
public void mvcTest() throws Exception {
mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void driverTest() {
this.driver.get("http://localhost:8080/");
assertEquals("Please log in", this.driver.findElement(By.xpath("/html/body/form/h1")).getText());
}
}
Если я его выполню, я получу java.lang.NoClassDefFoundError: org / openqa / selenium / remote / SessionNotFoundException, которое вызывается MockMvcHtmlUnitBuilder в методе before. Если я удалю строку, которая вызывает ошибку, и тест драйвера, mvcTest не будет успешным, потому что он получит 404 вместо 200.
Итак, следующее, что я сделал, - это удалил аннотации @WebAppConfiguration ("/ src / main / resources") и @ContextConfiguration (classes = {MvcConfig.class}) и добавил аннотацию @SpringBootTest (classes = Application.class). Теперь mvcTest работает, но если я снова добавлю код для драйвера, он все равно вызовет исключение SessionNotFoundException.
Итак, мой вопрос: как мне правильно создать MockMvc и WebDriver в Spring 5?




Я нашел решение своей проблемы. В документе Spring упоминается, что вам необходимо установить зависимость org.seleniumhq.selenium: selenium-htmlunit-driver. Последняя версия - 2.52.0. Теперь я добавил ту же версию удаленного драйвера:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
<version>2.52.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>2.52.0</version>
</dependency>
Я также просто использовал аннотацию @SpringBootTest, поэтому мой последний тестовый класс блокирует что-то вроде этого:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class exampleTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
private WebClient webClient;
private WebDriver driver;
@Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
this.webClient = MockMvcWebClientBuilder.webAppContextSetup(context, springSecurity()).build();
this.driver = MockMvcHtmlUnitDriverBuilder.webAppContextSetup(this.context, springSecurity()).build();
}
@Test
public void mvcTest() throws Exception {
mvc.perform(get("/login"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Please log in")));
}
@Test
public void clientTest() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
HtmlPage loginPage = webClient.getPage("http://localhost:8080/app/");
List<DomElement> pageList = loginPage.getElementsByTagName("h1");
DomElement page = pageList.get(0);
String text = page.getTextContent();
assertThat(text).isEqualTo("Please log in");
}
@Test
public void driverTest() {
driver.get("http://localhost:8080/app/");
assertEquals("Please log in",driver.findElement(By.xpath("/html/body/form/h1")).getText());
}
}
С текущими версиями Spring Boot и Spring Boot Test вы можете просто сделать следующее:
@SpringBootTest
@AutoConfigureMockMvc
public class MyApplicationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mockMvc;
@Autowired
private WebDriver driver;
@Test
void contextLoads() {
}
@Test
public void shouldReturnDefaultMessage() throws Exception {
this.driver.get("http://localhost:8080/app/");
assertEquals("Please log in",driver.findElement(By.xpath("/html/body/form/h1")).getText());
or
this.mockMvc.perform(get("/app")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string("true"));
}
}