背景:

今天偶然想测试下每个接口是否可以访问,网上找了一堆,基本没有一个在我的环境上实现了,没有一篇文章有详细的配置,于是只能用作参考自己进行琢磨,最后就出现了这样的文章也是给各位参考了,哈哈哈。

配置:

1. springboot2

                                                      

springboot junit 连接数据库 springboot junit controller_单元测试

 

2.spring-boot-starter-test
springboot2里面的这个变成了junit5,并不是junit4,注解有些不同,具体区别参考:,注释掉的代码就是去掉junit5,版本也是2.2.5

                       

springboot junit 连接数据库 springboot junit controller_junit_02

                                                 

springboot junit 连接数据库 springboot junit controller_单元测试_03

    

   最明显的标志应该就是引用的包不同,@Test注解引用的时候不要错了。

      junit5:    org.junit.jupiter.api

      junit4:    org.junit.

 

3.数据源(两种:一种是hikari,springboot默认    一种是druid,阿里巴巴的)

   3.1 hikari,pom没查到版本,只能xml看了。

                                                

springboot junit 连接数据库 springboot junit controller_junit_04

   3.2 druid

        

                                           

springboot junit 连接数据库 springboot junit controller_mvc_05

    注意一点,一定要加上配置

                                                                 

springboot junit 连接数据库 springboot junit controller_spring_06

    不只是就会报空指针错误,下图,挺明显的。

   

springboot junit 连接数据库 springboot junit controller_spring_07

    用默认的就注释掉druid这个,要不即使你配置了hikari,最后你会发现数据源还是druid,一开始我用的druid,想切换到hikari看看效果,结果怎么都是测试通过。要不是巧合去看日记也不会知道用的是druid数据源,也就不会有这个发现了。

注意:如果不是配置文件写的,是代码里写的要区别数据源。

                  hikari 是 DataSourceBuilder

                  druid 是 DruidDataSourceBuilder

         如果实在不知道用了哪个就看启动日记。应该在前面一点就能看到了,我的在11行左右

springboot junit 连接数据库 springboot junit controller_单元测试_08

4. Controller类

网上看的资料两种注解都有@RestController或者@Controller,测试了下都可以,我以@Controller为例。

@Controller
@RequestMapping("/user")
public class UserController {

    .....

    @ResponseBody
    @PostMapping("/login")
    public Result login(@Valid Info info) {
         .....
    }
}

 5. Test类

//个别引入的包
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
//这里配置文件没找到,估计是test的自启动里面就引入了的,查看了下版本org.springframework:spring-test:5.2.4.RELEASE
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;


//网上都是没有classes,但是我会报错。必须引入classes,且classes值不能乱写,要是你的springboot工程的启动类,要不没有后面MockMvc会报获取,不到请求URL的错误,即使你后台单独启动了springboot的项目。

@SpringBootTest(classes={PpSystemApplication.class})//启动整个springboot工程

//这个看名字就知道是自动MockMvc的了。开启后还要添加@Autowired自动注入
@AutoConfigureMockMvc
class UserControllerTest {


    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

//    网上有这种形式创建MockMvc的,结果我怎么都不行,这里也写出来
//    编辑一下,用这种方法的是用junit4的。
//    @Autowired
//    private WebApplicationContext webApplicationContext;

    @Autowired
    private MockMvc mvc;


    private MockHttpSession session;

    //junit5要用@BeforeEach,不是@Before
    @BeforeEach
    public void setupMockMvc(){

//        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
//        mvc = MockMvcBuilders.standaloneSetup(new WebController()).build();
        session = new MockHttpSession();

    }


        @Test
    void login() throws Exception {
        Info info= new Info();
        info.setUserName("admin");
        info.setPassword("admin");
        //请求路径不要错了
        MvcResult mvcResult = (MvcResult) mvc.perform(MockMvcRequestBuilders.post("/user/login")
                .accept(MediaType.ALL)
                .session(session)
                //这里要特别注意和content传参数的不同,具体看你接口接受的是哪种
                .param("userName",info.getUserName()).param("password",info.getPassword())
                  //传json参数,最后传的形式是 Body = {"password":"admin","userName":"admin"}
                  //.content(JSON.toJSON(info).toString().getBytes()) 
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();

        //得到返回代码
        int status = mvcResult.getResponse().getStatus();
        //得到返回结果
        String content = mvcResult.getResponse().getContentAsString();

        LOGGER.info(content);

    }

}

   配置好后,控制台可以看到的结果就是

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /user/login
       Parameters = {userName=[admin], password=[admin]}
          Headers = [Accept:"*/*"]
             Body = null
    Session Attrs = {uid=1, companyId=1, roles=[RoleDO(super=BaseEntity(id=1, createTime=null, updateTime=null, remark=超级管理员 权限最高), name=超级管理员, uid=null), RoleDO(super=BaseEntity(id=2, createTime=null, updateTime=null, remark=null), name=主管, uid=null), RoleDO(super=BaseEntity(id=3, createTime=null, updateTime=null, remark=null), name=采购员, uid=null)], org.apache.shiro.subject.support.DefaultSubjectContext_AUTHENTICATED_SESSION_KEY=true, org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY=admin, org.apache.shiro.web.session.HttpServletSession.HOST_SESSION_KEY=localhost, username=隔壁老王}

Handler:
             Type = com.heyjude.controller.UserController
           Method = com.heyjude.controller.UserController#login(LoginCheck)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Set-Cookie:"rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT", Content-Type:"application/json"]
     Content type = application/json
             Body = {"code":200,"message":"SUCCESS","data":null}
    Forwarded URL = null
   Redirected URL = null
          Cookies = [[MockCookie@656ec00d name = 'rememberMe', value = 'deleteMe', comment = [null], domain = [null], maxAge = 0, path = '/', secure = false, version = 0, httpOnly = false]]

OK,到此为止。