`

java项目的测试相关 springboot Junit

阅读更多

之前的编写代码的时候,由于时间限制等原因,一直觉得写单元测试是额外的工作量,也不爱写或者是开发完成之后再后补,有应付了事的嫌疑,没有做出单元测试的真是意义。但是这样往往会在修改完一个问题之后,可能引起其他问题而不自知。

所以单元测试还是有必要的。然后最近就研究了一下,应该用何种方式,什么工具去做测试,网上也找了一堆资料,基本上都是spock(groovy编写,还未使用过,后续试试),还有说要借鉴appfuse的测试思想去做(自行百度吧),什么DBUnit ,JUnit等等吧。

这些只是自己初略了解了下,但是具体有些也清楚怎么用,鉴于自己的需求,最后选择了JUnit,mockMvc,h2 database

 

自身系统情况:

使用Springboot + mybatis + mySql 实现的web项目

 

大致的思路是把三层都可以进行单元测试

1、dao

2、service

3、controller

 

1、dao

SpringBoot 整合H2测试Dao可以查看这篇日志: http://blog.csdn.net/mn960mn/article/details/54644908

https://segmentfault.com/a/1190000007002140

 

因为 h2的配置中初始话表数据的时候,如果直接是使用INIT=RUNSCRIPT FROM 这种引入插入数据的时候,但是不知道为什么 数据被插入了10遍,所以没办法只能更换方式,使用spring.datasource.data 进行初始化了。

 

## h2 database
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test;MODE=MYSQL;
##INIT=RUNSCRIPT FROM 'classpath:sql/init_table.sql'\\;RUNSCRIPT FROM 'classpath:sql/init_data.sql'  ## this i don't konw why it insert 10 datas
#spring.datasource.url=jdbc:h2:file:~/.h2/db_users;MODE=MYSQL;AUTO_SERVER=TRUE;   ## file save to local
spring.datasource.username=
spring.datasource.password=
spring.datasource.schema=classpath:sql/init_table.sql
spring.datasource.data=classpath:sql/init_data.sql
 

 

2、service 

测试service也比较简单,只需要执行service的扫描包就可以了。这样在测试类中就可以使用相应的bean了。

 

@Configuration
@ComponentScan(basePackages = {"com.test.service.**"})
public class ServiceConfiguration {

}
 

 

 3、controller

这个是在测试的时候问题比较多的地方,其实原本如果使用的是正常的mysql数据库(跟平时开发用的一个)也还好,但是为了实现单体测试和开发那个数据库分离,添加的这个H2数据库就出现问题了。

原因是我们自己重新定义了datasource 

 

@Configuration
@MapperScan({ "com.xxx.**.mapper"})
@ComponentScan({ "com.xxx.datasource"})
@Slf4j
public class MapperAdminConfiguration {
    @Bean
    @ConfigurationProperties(prefix="my.jdbc")
    public MyDataSource dataSource() {
       return (MyDataSource ) DataSourceBuilder.create()
                                                    .type(MyDataSource.class).build();
    }
} 

 

  注意:  以上代码有一些自身的逻辑,所以直接修改配置变为h2应该是不好用的,因为是后加的Test,所以不会动原来的代码

 

正常在Test文件中,指定 @SpringBootTest(classes={Application.class})就可以把需要的内容都进行加载初始化,但是由于通过@bean形式配置了datasource,那么加载时就会把配置文件中配置的默认的datasource进行覆盖,而去使用my.jdbc开头的配置信息。就没办法使用H2数据库了.

 

那么就想到了直接使用@SpringBootTest(classes={Application.class})这个。而是只引入自己需要的,就像Dao测试那样,然后自己就建立了一个

 

@Configuration
@ComponentScan(basePackages = {"com.xxxx.**")
public class ServiceConfiguration {

}
 

 

 

@RunWith(SpringRunner.class)  
/** 
 *  这里指定的classes是可选的。如果不指定classes,则spring boot会启动整个spring容器,很慢(比如说会执行一些初始化,ApplicationRunner、CommandLineRunner等等)。不推荐 
 *  指定的话,就只会初始化指定的bean,速度快,推荐 
 */  
@SpringBootTest(classes={DataSourceAutoConfiguration.class, MybatisAutoConfiguration.class, 
        MapperConfiguration.class,ServiceConfiguration.class})
@WebAppConfiguration
public class PlatformControllerTest {  
    
    MockMvc mvc;  
    
    @Autowired  
    WebApplicationContext webApplicationContext;  
    
    @Before  
    public void setUp() {  
        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();  
    }  
     
    @Test  
    public void list() throws Exception {  
        String uri = "/admin/admin/platform/list/all";  
        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON)).andReturn();  
        int status = mvcResult.getResponse().getStatus();  
        String result = mvcResult.getResponse().getContentAsString();  
        Assert.assertTrue("Wrong,status not 200 ,is " + status, status == 200);  
        Assert.assertFalse("Wrong,status not 200 ,is " + status, status != 200);  
    }  
    
    
    
    //@Test   
    public void testList(){
        RestTemplate restTemplate = new RestTemplate();//测试http请求的
        String url = "http://localhost:8080/admin/admin/platform/list/all";
        Map map = new HashMap<>();
        String result = restTemplate.getForObject(url, String.class, map);
        System.out.print(result+"=========");
    }
    
}  
 

 

但是问题出现了,因为返回的是对象,在list()方法返回的http状态一直是406,原因应该是在messageConverter的时候没有转,正常情况下SpringBoot是有一个WebMvcAutoConfiguration ,里边会添加上一些默认的HttpMessageConverters,自动进行转换的,但是现在不好用了,说明这个没有进行加载。

 

为什么使用 @SpringBootTest(classes={Application.class}) 可以加载进来,具体是怎么加载我也看不明白,无奈只能先看看Application类都有哪些东西吧

 

 

@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

}
 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {....}
 

 

   发现一个这样的注解 @EnableAutoConfiguration  

 相关解释: http://www.logicbig.com/tutorials/spring-framework/spring-boot/enable-auto-config/

 

Using @EnableAutoConfiguration is like using @Configuration annotation. It configures and wires our beans based on what @Bean methods we have defined in our configuration class. It does other additional configurations too, which includes configuring/invoking helper components (like embedded tomcat in web application). This mechanism works based on the jar dependencies available in the classpath. The jar are usually supplied via starter dependencies, but that's not the absolute requirement. The two things (starters and auto-configuration) are not dependent on each others.

使用@EnableAutoConfiguration就像使用@Configuration注释一样。 它根据我们在配置类中定义的@Bean方法来配置和连接我们的bean。 它还执行其他附加配置,其中包括配置/调用辅助组件(如Web应用程序中的嵌入式tomcat)。 此机制基于类路径中可用的jar依赖项起作用。 这个jar通常是通过启动器依赖来提供的,但这不是绝对的要求。 这两件事(启动器和自动配置)不依赖于彼此。

 

把这个标签加上之后,Ok了,可以进行messageConverter了。

 

那么现在就可以进行两个数据源的切换了,如果想使用开发时的mySql进行测试,可以直接在Test类中@SpringBootTest(classes={Application.class})就可以了,就可以初始化@bean定义的datasource,

如果想使用H2进行测试,那么就可以分别引入classes

@SpringBootTest(classes={DataSourceAutoConfiguration.class, MybatisAutoConfiguration.class, 
        MapperConfiguration.class,ServiceConfiguration.class})

 

springBoot就会去读取配置文件中的H2地址了。

 

出现问题的原因根本还是在于对于框架的本质原理不懂,只能看到表象的内容,其实最后就是一个注解引起的问题。

 

分享到:
评论

相关推荐

    Springboot-junit项目源码

    通过分析"Springboot-junit"项目源码,我们可以学习如何在SpringBoot项目中有效地进行测试,理解SpringBoot与JUnit的协同工作原理,以及如何利用Mockito进行模拟测试。这对于提升项目的质量和可维护性至关重要。

    springboot整合junit测试用例demo

    JUnit是一个广泛使用的Java单元测试框架,它简化了测试过程,使得测试更加便捷高效。 首先,我们需要在Spring Boot项目中引入JUnit的依赖。在`pom.xml`文件中添加以下Maven依赖: ```xml &lt;groupId&gt;org.spring...

    SpringBoot使用Junit进行单元测试

    Junit作为Java领域最常用的单元测试框架,与Spring Boot结合使用,可以方便地对应用程序进行测试。本文将深入探讨如何在Spring Boot项目中利用Junit进行单元测试。 首先,我们需要理解单元测试的基本概念。单元测试...

    单元测试案例junit +spring mvc +springboot

    JUnit是一个开源的Java测试框架,用于编写和运行可重复的单元测试。它提供了注解、断言方法和测试套件等特性,使得测试代码简洁易读。例如,`@Test`注解标记测试方法,`assertEquals`用于验证预期结果。JUnit还支持...

    SpringBoot-Junit

    SpringBoot-Junit是一个关于使用Spring Boot进行单元测试的项目,主要涵盖了如何在Spring Boot应用中集成和使用JUnit进行各种测试的实例。Spring Boot是Java开发中的一个流行框架,它简化了配置并提供了快速构建应用...

    SpringBoot第 3 讲:SpringBoot+Junit+Log4J

    在本讲中,我们将深入探讨如何在SpringBoot项目中整合JUnit测试框架以及Log4J日志系统。SpringBoot简化了Java应用的开发流程,而JUnit是广泛使用的单元测试工具,Log4J则是一款强大的日志记录框架。让我们一起了解...

    Java项目之springboot家具商城系统(源码)

    "Java项目之springboot家具商城系统(源码)" 是一个基于Java技术栈,利用Spring Boot框架构建的电子商务应用,专门针对家具销售行业。此项目提供了完整的源代码,允许开发者深入研究其架构和实现细节,或者直接用于...

    基于java的Layui+SpringBoot模板

    5. **测试文件**:JUnit或其他测试框架的测试类,用于验证功能的正确性。 6. **部署脚本**:如Dockerfile或部署到云平台的配置文件。 总的来说,这个项目模板提供了一个快速启动Java Web应用的起点,利用SpringBoot...

    spring boot Junit4配置

    Spring Boot作为流行的Java框架,简化了创建和管理微服务应用的过程,但如何有效地集成和配置JUnit4进行单元测试,对于初学者来说可能是个挑战。这篇文档将详细阐述如何在Spring Boot项目中配置JUnit4,并提供使用...

    Springboot_junit

    下面将详细介绍如何在SpringBoot项目中使用JUnit进行测试。 首先,我们需要在项目的`pom.xml`文件中添加JUnit的依赖。SpringBoot 1.5.6版本通常会包含对JUnit 4的支持,但如果需要使用更新的JUnit 5,需要单独引入...

    Junit 单元测试完整案例

    Junit作为Java领域最常用的单元测试框架,为开发者提供了简单易用的API来进行测试。本案例涵盖了Spring和Struts两大框架的单元测试,旨在帮助开发者掌握如何对这两个流行的Java Web框架进行有效的测试。 一、Junit...

    springboot_junit.zip

    下面是一个简单的示例,展示如何在SpringBoot项目中使用JUnit进行单元测试: ```java import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory....

    Java项目之springboot驾校管理系统(源码)

    另外,系统可能还会利用Spring Boot的集成测试框架,如JUnit和Mockito,来编写单元测试,确保代码的质量和稳定性。测试是软件开发中不可或缺的一部分,它可以帮助我们在早期发现潜在的问题,提高系统的可靠性。 ...

    SpringbootJunitTest.java

    SpringBoot的junit测试用例,接口测试和service测试、dao测试,接口测试用的是MockMvc

    Java项目之基于SpringBoot的高校教学档案管理系统设计与实现 (源码 + 说明文档 + 演示视频)

    本项目是针对高校教学档案管理的一套完整解决方案,利用了Java技术栈以及SpringBoot框架进行构建。SpringBoot以其简化开发、快速启动、自动配置的特性,成为现代Java Web应用的首选框架。本系统旨在提高高校教学档案...

    SpringBoot整合Junit实例过程解析

    SpringBoot整合了Junit后,在写了Mapper接口后,可直接通过Junit进行测试,不用再写Controller层,不用启动引导类之后通过页面的形式一层一层的调用。这可以大大提高开发效率和测试效率。 二、SpringBoot整合Junit...

    springboot空白项目自用

    9. **测试**:SpringBoot提供了`spring-boot-starter-test`模块,包含了JUnit、Mockito、Spring Test等测试工具,方便进行单元测试和集成测试。 在"ctj"这个压缩包中,可能包含了上述提到的一些基本项目结构和配置...

    Java项目之springboot福聚苑社区团购(源码)

    "Java项目之springboot福聚苑社区团购(源码)" 这个标题表明这是一个基于Java编程语言的项目,具体使用了Spring Boot框架来开发一个社区团购系统。Spring Boot是Spring框架的一个扩展,它简化了Spring应用程序的...

    SpringBoot 多模块 Serivce 层单元测试

    对于Spring Boot项目,通常会使用`spring-boot-starter-test`依赖,它包含了JUnit、Mockito、Spring Test等测试相关的库。在pom.xml或build.gradle中,确保这些测试依赖已经被引入。 2. **创建测试类**:测试类一般...

Global site tag (gtag.js) - Google Analytics