java Spring单元测试详解

Wesley13
• 阅读 715

介绍在Spring的框架下,做单元测试的两种办法。

一、使用spring中对Junit框架的整合功能

    除了junit4和spring的jar包,还需要spring-test.jar。引入如下依赖:

<dependency>  
    <groupId>org.springframework</groupId>  
    <artifactId>spring-test</artifactId>  
    <version>3.1.1.RELEASE</version>  
</dependency>  

 @ContextConfiguration需要配上spring的配置文件,这样就可以在测试类中使用注解简单的注入需要的bean了。简单高效。

import com.zhisland.weizhan.common.configs.Contants;
import com.zhisland.weizhan.mp.model.sendMsg.SendMsgLog;
import com.zhisland.weizhan.mp.service.RedisCommonService;
import com.zhisland.weizhan.mp.service.SendMsgService;
import com.zhisland.weizhan.mp.service.WmpUserService;
import com.zhisland.wz.model.WxAppConfig;
import com.zhisland.wz.service.MpWeixinApi;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:wmp-servlet.xml")
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class RedisServiceImplTest extends AbstractTransactionalJUnit4SpringContextTests {
    private final static Logger LOGGER = LoggerFactory.getLogger(meetingTest.class);
    @Autowired
    private SendMsgService sendMsgService;
    @Autowired
    private MpWeixinApi mpWeixinApi;
    @Autowired
    private WmpUserService wmpUserService;
    @Autowired
    private Contants contants;
    @Autowired
    private RedisCommonService redisCommonService;

    @Before
    public void setUp() throws Exception {
        
    }

    @After
    public void tearDown() throws Exception {

    }

    @Test
    public void testGet() {

        WxAppConfig wxAppConfig = mpWeixinApi.getWeixinAppConfigByAppId(contants.appId);
        List<SendMsgLog> sendMsgLogList = sendMsgService.getWaittingLogListByMsgId(wxAppConfig.getId(), 4, 3, 0);
        int first = sendMsgLogList.get(0).getId();
        int last = sendMsgLogList.get(sendMsgLogList.size() - 1).getId();
        LOGGER.info("first={},last={}", first, last);

//        redisCommonService.set("wjt_subscribe_return_url_2","fff哈哈");
////        System.out.println("get redis value="+redisCommonService.get("wjt_subscribe_return_url_2"));
//        System.out.println("get redis value="+redisCommonService.getString("wjt_subscribe_return_url_1"));
//        System.out.println("get redis value="+redisCommonService.getString("wjt_subscribe_return_url_o8cvjt0Ua1fJDJ0iNwfvrBGi9sbc"));
    }


}

二、手动加载spring的配置文件,并启动spring容器

public class ReadDaoImplTest {  
      
    public  static void main(String[] args){  
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  
        context.start();  
  
        ReadDao fqaService = (ReadDao) context.getBean("readDao");  
        System.out.println(fqaService);  
    }  
      
}  

三、详解

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.GenericXmlContextLoader;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.cgodo.mvc.service.Result;
import com.security.entity.SecurityPermission;
import com.security.model.AddSecurityPermissionModel;
import com.security.model.UpdateSecurityPermissionModel;
import com.security.service.SecurityPermissionI;

/**
 * 
 * 权限服务层测试类
 */

//测试时需要的

@RunWith(value = SpringJUnit4ClassRunner.class) //在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境
@ContextConfiguration(locations = {"classpath:/com/security/resource/spring/context/application/applicationContext.xml"} , loader = GenericXmlContextLoader.class)//【@ContextConfiguration 用来指定加载的Spring配置文件的位置,会加载默认配置文件,  

@ContextConfiguration 注解有以下两个常用的属性:locations:可以通过该属性手工指定 Spring 配置文件所在的位置,可以指定一个或多个 Spring 配置文件用,分开。如下所示: @ContextConfiguration(locations={“aa/aa.xml”,” aa/bb.xml”})

inheritLocations:是否要继承父测试用例类中的 Spring 配置文件,默认为 true。】

@DirtiesContext(classMode = ClassMode.AFTER_CLASS) //@DirtiesContext 在测试方法上出现这个注解时,表明底层Spring容器在该方法的执行中被“污染”,从而必须在方法执行结束后重新创建(无论该测试是否通过)。

@TransactionConfiguration( transactionManager = "transactionManager" , defaultRollback = false) //【@TransactionConfiguration 为配置事务性测试定义了类级别的元数据。PlatformTransactionManager默认的实例叫transactionManager, 如果需要的PlatformTransactionManager不是“transactionManager”的话,那么可以显式配置驱动事务的PlatformTransactionManager的bean的名字。此外, 可以将defaultRollback标志改为false,表示不回滚。通常, @TransactionConfiguration与@ContextConfiguration搭配使用。

@ContextConfiguration
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)】

@Transactional //开启类级别的事物
public class TestSecurityPermissionService {

//注解生成SecurityPermissionI 的代理
@Autowired
 SecurityPermissionI securityPermissionI;

  
 /**
  * 描述:初始化测试数据
  * @throws InvocationTargetException 
  * @throws IllegalAccessException 
  */
 @Before
 public void before() throws IllegalAccessException, InvocationTargetException{
  //添加删除测试数据
  SecurityPermission securityPermissionDelete = new SecurityPermission();
  securityPermissionDelete.setPermissionId("TEST_permissionId-Delete");
  securityPermissionDelete.setPermissionDescription("TEST_权限描述信息-Delete");
  securityPermissionDelete.setPermissionType("TEST_权限类型-Delete");
  Result<List> resultDelete = securityPermissionI.getPermissionsByType(securityPermissionDelete);
  
  AddSecurityPermissionModel addSecurityPermissionModelDelete = new AddSecurityPermissionModel();
  BeanUtils.copyProperties(addSecurityPermissionModelDelete, securityPermissionDelete);
  if(resultDelete.getData() == null){
   securityPermissionI.addPermission(addSecurityPermissionModelDelete);
  }
  
  //添加删除测试数据
  SecurityPermission securityPermissionDeleteNot = new SecurityPermission();
  securityPermissionDeleteNot.setPermissionId("TEST_permissionId-DeleteNot");
  securityPermissionDeleteNot.setPermissionDescription("TEST_权限描述信息-DeleteNot");
  securityPermissionDeleteNot.setPermissionType("TEST_权限类型-DeleteNot");
  Result<List> resultDeleteNot = securityPermissionI.getPermissionsByType(securityPermissionDeleteNot);
  
  AddSecurityPermissionModel addSecurityPermissionModelDeleteNot = new AddSecurityPermissionModel();
  BeanUtils.copyProperties(addSecurityPermissionModelDeleteNot, securityPermissionDeleteNot);
  if(resultDeleteNot.getData() == null){
   securityPermissionI.addPermission(addSecurityPermissionModelDeleteNot);
  }
  
  
  
  //添加更新测试数据
  SecurityPermission securityPermissionUpdate = new SecurityPermission();
  securityPermissionUpdate.setPermissionId("TEST_permissionId-Update");
  securityPermissionUpdate.setPermissionDescription("TEST_权限描述信息-Update");
  securityPermissionUpdate.setPermissionType("TEST_权限类型-Update");
  Result<List> resultUpdate = securityPermissionI.getPermissionsByType(securityPermissionUpdate);
  
  AddSecurityPermissionModel addSecurityPermissionModelUpdate = new AddSecurityPermissionModel();
  BeanUtils.copyProperties(addSecurityPermissionModelUpdate, securityPermissionUpdate);
  if(resultUpdate.getData() == null){
   securityPermissionI.addPermission(addSecurityPermissionModelUpdate);
  }
  
  //添加查询测试数据
  SecurityPermission securityPermissionSelect = new SecurityPermission();
  securityPermissionSelect.setPermissionId("TEST_permissionId-Select");
  securityPermissionSelect.setPermissionDescription("TEST_权限描述信息-Select");
  securityPermissionSelect.setPermissionType("TEST_权限类型-Select");
  Result<List> resultSelect = securityPermissionI.getPermissionsByType(securityPermissionSelect);

  AddSecurityPermissionModel addSecurityPermissionModelSelect = new AddSecurityPermissionModel();
  BeanUtils.copyProperties(addSecurityPermissionModelSelect, securityPermissionSelect);
  if(resultSelect.getData() == null){
   securityPermissionI.addPermission(addSecurityPermissionModelSelect);
  }
  
 }
 
 //@Test 这个将不会被测试
 public void Test(){
  boolean bb = false;
  Assert.assertFalse(bb);
 }

 @Rollback(true)//设置测试后回滚
 @Transactional//为方法开启事物
 @Test //标注要测试的方法,不添加@Test将不会进行测试
 public void TestAddPermission(){
  SecurityPermission securityPermission = new SecurityPermission();
  securityPermission.setPermissionId("TEST_permissionId-Add");
  securityPermission.setPermissionDescription("TEST_权限描述信息-Add");
  securityPermission.setPermissionType("TEST_权限类型-Add");
  
  AddSecurityPermissionModel model = new AddSecurityPermissionModel();
  try {
   BeanUtils.copyProperties(model, securityPermission);
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  //测试权限不存在的情况
  Result isNotExists;
  try {
   isNotExists = securityPermissionI.addPermission(model);

   Assert.assertTrue(isNotExists.isSuccess());
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  //测试权限已存在的情况
  Result isExists;
  try {
   isExists = securityPermissionI.addPermission(model);
   Assert.assertFalse(isExists.isSuccess());
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
  }

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
凯文86 凯文86
3年前
Spring Boot API 服务测试指南
SpringBoot除了简化了Spring应用的开发,同时也简化了Spring应用的测试。它内置支持各种常用测试工具,包括SpringTest、JUnit、TestNG、Mockito、AssertJ等。本文将讲解如何编写单元测试和集成测试来保障SpringBootAPI应用不同层级代码的质量,其中会涉及到使用嵌入式的H2数据库
Stella981 Stella981
3年前
2020面试整理【java】
前言:java框架面试题总结2020年4月1日spring面试题1.你对spring的理解?与springmvc和springboot的区别?(经常被问到)Spring是个Java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。
Wesley13 Wesley13
3年前
Java基础学习总结(24)——Java单元测试之JUnit4详解
Java单元测试之JUnit4详解与JUnit3不同,JUnit4通过注解的方式来识别测试方法。目前支持的主要注解有:@BeforeClass 全局只会执行一次,而且是第一个运行@Before 在测试方法运行之前运行@Test(http://my.oschina.net/azibug) 测试方法
Stella981 Stella981
3年前
Spring IoC、AOP、Transaction、MVC 归纳小结
前言Spring的一些概念和思想关于IOC关于AOPSpring与web整合的原理前言如果说有什么框架是Java程序员必然会学习、使用到的,那么Spring肯定是其中之一。本篇博客,将根据博主在日常工作中对Spring的使
Stella981 Stella981
3年前
JUnit
一、会用Spring测试套件的好处在开发基于Spring的应用时,如果你还直接使用Junit进行单元测试,那你就错过了Spring为我们所提供的饕餮大餐了。使用Junit直接进行单元测试有以下四大不足:1)导致多次Spring容器初始化问题根据JUnit测试方法的调用流程,每执行一个测试方法都会创建一个测试用例的实例并调用setUp()方法。由于
Wesley13 Wesley13
3年前
Java中的参数验证(非Spring版)
1\.Java中的参数验证(非Spring版)1.1.前言为什么我总遇到这种非正常问题,我们知道很多时候我们的参数校验都是放在controller层的传入参数进行校验,我们常用的校验方式就是引入下列的jar包,在参数中添加@Validated,并对Bean对象的参数做不
Stella981 Stella981
3年前
Spring4+Spring MVC+MyBatis整合思路
1、Spring框架的搭建这个很简单,只需要web容器中注册org.springframework.web.context.ContextLoaderListener,并指定spring加载配置文件,那么spring容器搭建完成。(当然org.springframework的核心jar包需要引入)当然为了更加易用支持J2EE应用,一般我们还会加上如下
Stella981 Stella981
3年前
Dubbo zookeeper 初探【转】
先把zookeeper在本地给安装好,这里的话讲述了两个工程一个工程是提供服务的,一个工程是调用服务的,因为dubbo是跟spring进行无缝连接的,故功能配置在spring的配置文件中,跟spring进行整合开发1、工程是以maven进行构建的,使用的jar包如下:!(https://static.oschina.net/uploads/i
Wesley13 Wesley13
3年前
Java Spring 教程网站推荐
Spring是一个企业Java框架。它旨在简化JavaEE开发并提高开发人员的生产力。Spring利用控制反转和依赖注入来促进良好的软件编码实践并缩短开发时间。Spring框架是Java平台的应用程序框架和控制容器的倒置。该框架的核心功能可以被任何Java应用程序使用。尽管该框架没有强加任何特定的编程模型,但是它已在Java社区中流行起来,它包括提供各种