springboot集成测试-小例子

环境

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 {
...

上面是书中的写法, 但是在我的环境中,会报错;
①因为@SpringApplicationConfigurationspringboot1.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 集成测试

你可能感兴趣的:(springboot)