MacBook Pro
idea:2019.1
Java:1.8
springboot:2.1.4
最近在看springboot
实战,看到第四章节测试Web应用测试
->模拟springMVC
时,跟着书中走,总是出问题;这里记录下:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(
classes = ReadingListApplication.class)
@WebAppConfiguration
public class MockMvcWebTests {
...
上面是书中的写法, 但是在我的环境中,会报错;
①因为@SpringApplicationConfiguration
在springboot1.5+
时,已经去掉了,应该使用@SpringbootTest
;
②@WebAppConfiguration
我把它替换成@AutoConfigureMockMvc
,因为不换总是报错。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ReadingListController.class)
@WebAppConfiguration
public class MockMvcWebTests {
...
会报错:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'readingListController': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.misssad.springbootdemo.repository.ReadingListRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
这个错是说,需要无参构造器,无法创建bean
但是 代码里就是构造器注入,就是要用那个有参构造器的;不能无参,况且,无参依然报错。
和
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.misssad.springbootdemo.repository.ReadingListRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
这个错是说,上下文里面没有ReadingListRepository
这个bean
因为ReadingListController
类里面依赖了ReadingListRepository
,但是视乎这个模拟器只只加载了ReadingListController
,它的依赖bean
没有加载;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ReadingListController.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@WebAppConfiguration
public class MockMvcWebTests {
...
错误变为:
java.lang.IllegalStateException: @WebAppConfiguration should only be used with @SpringBootTest when @SpringBootTest is configured with a mock web environment. Please remove @WebAppConfiguration or reconfigure @SpringBootTest
这段是我没有看懂的,其大概的意思:
当@SpringBootTest配置了模拟Web环境时,@ WebAppConfiguration只能与@SpringBootTest一起使用。
请删除@WebAppConfiguration或重新配置@SpringBootTest
明明就是web环境啊,为什么会报这个错,目前没有搞懂???
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ReadingListController.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MockMvcWebTests {
...
报了个这样的错误:
Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean
也就是Servlet
这个容器bean
,它没有找到。
最后我把@SpringBootTest
中的classes
参数去掉就行了,也就是最终代码;
所以最终代码就变成了;(相关代码我就不贴了,都是参考springboot实战.pdf
那边书的)
import com.misssad.springbootdemo.controller.ReadingListController;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MockMvcWebTests {
@Autowired
private WebApplicationContext webContext;
private MockMvc mockMvc;
/*产生一个MockMvc实例
有了这个实例,就可以写测试用例了
*/
@Before
public void setupMockMvc(){
mockMvc = MockMvcBuilders.webAppContextSetup(webContext)
.build();
System.out.println("-------运行成功------");
}
/*①向readingList发起一个get请求;
* ②希望该请求处理成功(isOK()会判断HTTP200响应码);
* ③视图的逻辑名称为readingList;
* ④判断模型包含一个名为books的属性
* ⑤该属性是个空集合
*/
@Test
public void homePage() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/readingList"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.view().name("readList"))
.andExpect(MockMvcResultMatchers.model().attributeExists("books"))
.andExpect(MockMvcResultMatchers.model()
.attribute("books", Matchers.is(Matchers.empty())));
}
}
参考地址:
https://stackoverflow.com/a/42788074
Spring Boot 集成测试