通过模拟服务进行弹簧控制器测试
Posted
技术标签:
【中文标题】通过模拟服务进行弹簧控制器测试【英文标题】:spring controller test by mock service 【发布时间】:2019-05-23 09:56:33 【问题描述】:使用 Mocking 和单元测试助手更喜欢 Spring 测试:
模拟服务替换多个依赖项
enter image description here
@Controller
@RequestMapping("/people")
public class PeopleController
@Autowired
protected PersonService personService;
@GetMapping
public ModelAndView people(Model model)
for (Person person: personService.getAllPeople())
model.addAttribute(person.getName(), person.getAge());
return new ModelAndView("people.jsp", model.asMap());
私有 MockMvc mockMvc:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PeopleControllerTest
@Autowired
PersonService personService;
private MockMvc mockMvc;
@Configuration
static class Config
// Other beans
@Bean
public PersonService getPersonService()
return mock(PersonService.class);
@Test
public void testPeople() throws Exception
// When
ResultActions actions = mockMvc.perform(get("/people"));
我想运行mockMvc
时出错
java.lang.NullPointerException
【问题讨论】:
mockMvc
是什么?
@Ravi 服务器端 Spring MVC 测试的主要入口点
你能分享这门课吗?
【参考方案1】:
执行以下步骤:
创建服务模拟而不是服务原始 (“PersonServiceMock”)
用服务模拟替换服务原始
@Autowired
PersonService personService;
@Autowired
PeopleController peopleController;
private MockMvc mockMvc;
@Before
public void setup()
peopleController = new PeopleController(new personServiceMock());
mvc = MockMvcBuilders.standaloneSetup(peopleController).build();
@Configuration
static class Config
// Other beans
@Bean
public PersonService getPersonService()
return mock(PersonService.class);
@Test
public void testPeople() throws Exception
// When
ResultActions actions = mockMvc.perform(get("/people"));
【讨论】:
【参考方案2】:那是因为您从未在代码中初始化mockMvc
,而您访问它的点会导致nullPointerException
。您需要在使用它之前对其进行初始化,并且由于您的类中的多个测试可能正在使用它,因此最好的方法是使用带有@before
注释的setup()
方法。试试下面:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PeopleControllerTest
@Autowired
PersonService personService;
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup()
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
@Configuration
static class Config
// Other beans
@Bean
public PersonService getPersonService()
return mock(PersonService.class);
@Test
public void testPeople() throws Exception
// When
ResultActions actions = mockMvc.perform(get("/people"));
【讨论】:
【参考方案3】:从源代码中我看到 mockMvc 没有任何价值,这就是为什么它在这行代码中命中“java.lang.NullPointerException”:
ResultActions actions = mockMvc.perform(get("/people"));
为了让它运行,我认为首先需要为 mockMvc 赋予价值。 通过构造函数:
@Test
public void testPeople() throws Exception
mockMvc = new MockMvc();
// When
ResultActions actions = mockMvc.perform(get("/people"));
或自动接线:
@Autowired
MockMvc mockMvc
取决于 MockMvc 类的用途
【讨论】:
以上是关于通过模拟服务进行弹簧控制器测试的主要内容,如果未能解决你的问题,请参考以下文章