使用springboot对各个层的代码进行测试

简介: 因为近段时间在一个系统,后端代码使用的技术栈是spring boot (版本1.5.12.RELEASE)、alibaba-spring-boot (版本1.5.12.0-SNAPSHOT)、pandora-boot (版本2018-05-release),写好各种mapper、service、c.

因为近段时间在一个系统,后端代码使用的技术栈是spring boot (版本1.5.12.RELEASE)、alibaba-spring-boot (版本1.5.12.0-SNAPSHOT)、pandora-boot (版本2018-05-release),写好各种mapper、service、controller层的代码之后免不了要进行测试,最高效的测试方法还是写单元测试,如果自己在本地把服务起来,页面上点点点,那是极其low极力不推荐的!

下面就介绍一下各个层的测试基类的写法:

pom依赖如下:

<!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.taobao.pandora</groupId>
            <artifactId>pandora-boot-test</artifactId>
            <scope>test</scope>
        </dependency>

一、mapper层的测试

测试基类如下:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Rollback(false)
public class BaseMapperTest {
}

说明:
1、使用@MybatisTest,如果不加注解@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE),那么mybatis使用的是内存数据库,并不是真实的tddl的数据库,会报表不存在的错,官方文档在此:http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/
Using a real database
The In-memory embedded databases generally work well for tests since they are fast and don’t require any developer installation. However if you prefer to run tests against a real database, you can use the @AutoConfigureTestDatabase as follow:
2、@Rollback(false) 单测完成默认会将数据回滚,如果不想回滚,想保留在数据库中,要加(false)。

二、service层的测试

测试基类如下:

@RunWith(PandoraBootRunner.class)
@DelegateTo(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@SpringBootTest(classes = TestServiceConfiguration.class)
public class BaseServiceTest {
}

说明:在做service层的测试的时候,还是遇到一些问题,网上各种搜资料,很多例子在进行service层的测试时将dao层进行了mock的办法,但我并不想mock,经过一顿勇猛猜测,最后终于跑通了。比起mapper层的测试,多了这么几个注解:
@RunWith(PandoraBootRunner.class)
@DelegateTo(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
参考资料: http://gitlab.alibaba-inc.com/middleware-container/pandora-boot/wikis/test

为什么要加最后一个注解呢,这个要看自己的项目来定,一开始写的是@SpringBootTest(classes = Application.class),发现运行测试的时候总有一些service无法注入,报错: No qualifying bean of type 'xxx' available。
后来按照网上的解决办法,自己写了个TestConfiguration,代码如下:

@ComponentScan(basePackages={
        "com.alibaba.ais.feds.mapper",
        "com.alibaba.ais.feds.service"})
@SpringBootApplication
public class TestServiceConfiguration {
    public  static  void main(String[] args){
        SpringApplication.run(TestServiceConfiguration.class, args);
    }
}

具体的原因等空了还需要再推敲一下,遇到问题不能仅仅靠猜。

三、controller层的测试:

基类如下:

@RunWith(PandoraBootRunner.class)
@DelegateTo(SpringRunner.class)
@ActiveProfiles("test")
public class BaseAjaxControllerTest {
}

一般在进程controller层测试的时候,会将service层进行mock,我介绍2种写法,分别是mock的方法和不mock的方法:
1、不mock的方法:

@WebMvcTest(value = DrillScenarioAjaxController.class, secure = false)
public class DrillScenarioAjaxControllerTest extends BaseAjaxControllerTest{

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ScenarioService scenarioService;


    @Test
    public void testExecScenario(){
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/scenario/42/exec?employeeId=57524")
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
        try {
            MvcResult result = mockMvc.perform(requestBuilder).andReturn();
            MockHttpServletResponse response = result.getResponse();
            Assert.assertThat(response.getStatus(), equalTo(200));
            System.out.println(response.getContentAsString());
        }
        catch (Exception e){
            System.out.println(e.fillInStackTrace());
        }

    }

    @Configuration
    @EnableWebMvc
    @Import({TestControllerConfiguration.class})
    static class Config {
    }
}
@ComponentScan(basePackages={
        "com.alibaba.ais.feds.mapper",
        "com.alibaba.ais.feds.service",
        "com.alibaba.ais.feds.controller"})
@SpringBootApplication
public class TestControllerConfiguration {
    public  static  void main(String[] args){
        SpringApplication.run(TestControllerConfiguration.class, args);
    }
}

2、mock的方法:

@WebMvcTest(value = ApplicationAjaxController.class, secure = false)
public class ApplicationAjaxControllerTest extends BaseAjaxControllerTest{
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    //@Autowired
    private ApplicationApi applicationApi;

    @Autowired
    private TokenService tokenService;

    @Test
    public void test() throws Exception {
        String mockResult = "{\"object\":{\"applications\":[{\"name\":\"app-center\",\"id\":112608}]},\"successful\":true}";

        Mockito.when(
                applicationApi.queryApps(Mockito.anyMap())).thenReturn(JSON.parseObject(mockResult));
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/queryAppsByNameFromAone?query=app-center")
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
        MvcResult result = mockMvc.perform(requestBuilder).andReturn();
        MockHttpServletResponse response = result.getResponse();
        Assert.assertThat(response.getStatus(), equalTo(200));
        Assert.assertThat(response.getContentAsString(),equalTo(mockResult));
    }
    
    @Configuration
    @EnableWebMvc
    @Import({TestControllerConfiguration.class})
    static class Config {
    }
}

注意:
一开始跑controller层测试的时候,response 总是404,后来发现一定要加上 @EnableWebMvc注解,问题解决。

好了,测试跑通,现在感觉想怎么测,就怎么测。

目录
相关文章
|
11月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
1148 3
|
11月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
637 1
|
算法 IDE Java
Java 项目实战之实际代码实现与测试调试全过程详解
本文详细讲解了Java项目的实战开发流程,涵盖项目创建、代码实现(如计算器与汉诺塔问题)、单元测试(使用JUnit)及调试技巧(如断点调试与异常排查),帮助开发者掌握从编码到测试调试的完整技能,提升Java开发实战能力。
986 0
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
10月前
|
安全 Java 测试技术
《深入理解Spring》单元测试——高质量代码的守护神
Spring测试框架提供全面的单元与集成测试支持,通过`@SpringBootTest`、`@WebMvcTest`等注解实现分层测试,结合Mockito、Testcontainers和Jacoco,保障代码质量,提升开发效率与系统稳定性。
|
10月前
|
Java 测试技术 数据库连接
【SpringBoot(四)】还不懂文件上传?JUnit使用?本文带你了解SpringBoot的文件上传、异常处理、组件注入等知识!并且带你领悟JUnit单元测试的使用!
Spring专栏第四章,本文带你上手 SpringBoot 的文件上传、异常处理、组件注入等功能 并且为你演示Junit5的基础上手体验
1184 3
|
11月前
|
人工智能 边缘计算 搜索推荐
AI产品测试学习路径全解析:从业务场景到代码实践
本文深入解析AI测试的核心技能与学习路径,涵盖业务理解、模型指标计算与性能测试三大阶段,助力掌握分类、推荐系统、计算机视觉等多场景测试方法,提升AI产品质量保障能力。
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
434 0
|
安全 Java 测试技术
Java 项目实战中现代技术栈下代码实现与测试调试的完整流程
本文介绍基于Java 17和Spring技术栈的现代化项目开发实践。项目采用Gradle构建工具,实现模块化DDD分层架构,结合Spring WebFlux开发响应式API,并应用Record、Sealed Class等新特性。测试策略涵盖JUnit单元测试和Testcontainers集成测试,通过JFR和OpenTelemetry实现性能监控。部署阶段采用Docker容器化和Kubernetes编排,同时展示异步处理和反应式编程的性能优化。整套方案体现了现代Java开发的最佳实践,包括代码实现、测试调试
400 0