• PowerMock+SpringMVC整合并测试Controller层方法


    PowerMock扩展自Mockito,实现了Mockito不支持的模拟形式的单元测试。PowerMock实现了对静态方法、构造函数、私有方法以及final方法的模拟支持,对静态初始化过程的移除等强大的功能。(官方)

    接下来,通过实例来实现对SpringMVC的Controller层的方法模拟测试。

    一、maven引入PowerMock相应的Jar文件

     1 <dependency>  
     2   <groupId>org.powermock</groupId>  
     3   <artifactId>powermock-api-mockito</artifactId>  
     4   <version>1.6.5</version>  
     5 </dependency>  
     6   
     7 <dependency>  
     8   <groupId>org.powermock</groupId>  
     9   <artifactId>powermock-module-junit4</artifactId>  
    10   <version>1.6.5</version>  
    11 </dependency>  	

    二、单元测试基类

     1 import org.junit.runner.RunWith;  
     2 import org.powermock.core.classloader.annotations.PowerMockIgnore;  
     3 import org.powermock.modules.junit4.PowerMockRunner;  
     4 import org.powermock.modules.junit4.PowerMockRunnerDelegate;  
     5 import org.springframework.test.context.ContextConfiguration;  
     6 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
     7 import org.springframework.test.context.transaction.TransactionConfiguration;  
     8 import org.springframework.transaction.annotation.Transactional;  
     9   
    10 @RunWith(PowerMockRunner.class)  //使用PowerMockRunner运行时  
    11 @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)  //委派给SpringJUnit4ClassRunner  
    12 @ContextConfiguration (locations={"classpath:META-INF/app_config/context/context-*.xml"}) //加载配置文件  
    13 @Transactional  
    14 @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)  
    15 @PowerMockIgnore({"javax.management.*"}) //忽略一些mock异常  
    16 public class BaseJunit4 {  
    17       
    18 }  

    @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class):PowerMock与Spring整合时最重要的配置

    @TransactionConfiguration(transactionManager="transactionManager",defaultRollback =true): 这里的事务关联到项目的配置文件中的事务控制器("transactionManager"),同时指定事物自动回滚(defaultRollback= true),以此对数据库不会产生数据污染。

    三、单元测试类

     1 import static org.junit.Assert.assertEquals;    
     2     
     3 import java.util.HashMap;    
     4 import java.util.Map;    
     5     
     6 import javax.annotation.Resource;    
     7     
     8 import org.junit.Before;    
     9 import org.junit.Test;    
    10 import org.mockito.InjectMocks;    
    11 import org.powermock.api.mockito.PowerMockito;    
    12 import org.powermock.core.classloader.annotations.PrepareForTest;    
    13 import org.springframework.beans.factory.annotation.Autowired;    
    14 import org.springframework.mock.web.MockHttpServletRequest;    
    15 import org.springframework.test.util.ReflectionTestUtils;    
    16     
    17 import com.asset.action.IAssetScrapHandleAction;    
    18 import com.asset.controller.AssetScrapHandleController;    
    19 import com.framework.core.persistence.pagination.CurrentPage;    
    20   
    21 @PrepareForTest({OrgUtils.class,UserUtils.class})  
    22 public class ScrapAssetApplyActionImplTest extends BaseJunit4{  
    23     @InjectMocks@Autowired  
    24     private static AssetScrapHandleController controller;  
    25       
    26     @Resource(name=IAssetScrapHandleAction.ACTION_ID)  
    27     private IAssetScrapHandleAction aSHAction;  
    28   
    29     @Before  
    30     public  void befor(){  
    31         //依赖注入相应的action  
    32         ReflectionTestUtils.setField(controller, "assetScrapHandleAction", aSHAction);  
    33     }  
    34   
    35     @Test  
    36     public void testCreateHandleNum() {  
    37         Map map = new HashMap();  
    38         PowerMockito.mockStatic(OrgUtils.class);PowerMockito.mockStatic(UserUtils.class);  
    39           
    40         //自定义模拟静态方法返回的对象1  
    41         OrganizationBO bo = new OrganizationBO();  
    42         bo.setLeavel("L0");  
    43         PowerMockito.when(UserUtils.getLoginUserCom()).thenReturn(bo);  
    44           
    45         //自定义模拟静态方法返回的对象2  
    46         UserBO userbo = new UserBO();  
    47         userbo.setOrgCode("1100");  
    48         LoginUser loginUser = new LoginUser(userbo);  
    49         PowerMockito.when(UserUtils.getUser()).thenReturn(loginUser);  
    50           
    51         //模拟请求  
    52         MockHttpServletRequest request = new MockHttpServletRequest();  
    53         request.setParameter("time", "2016-01-01");  
    54         CurrentPage page = new CurrentPage();  
    55         page.setRows(25);  
    56         map = controller.getDataList(request, page);   
    57         boolean actual = true;   
    58         assertEquals(Integer.valueOf(map.get("total").toString())>=1, actual);   
    59     }  
    60 }    

    对Controller测试时,还需要由Controller层中的Action去执行相应的业务代码,对于Action的依赖注入就可以非常方便的使用ReflectionTestUtils.setField(controller,"assetScrapHandleAction",aSHAction)(非常重要),将aSHAction注入到controller层中的属性名为assetScrapHandleAction中  
    @PrepareForTest({OrgUtils.class,UserUtils.class}) 注解一定要放到类上,或者基类上也可以,千万不能放到方法上。如果在方法上,会导致每执行一次test方法,都会委托SpringJUnit4ClassRunner去加载一次上下文配置,将直接导致内存耗尽。

    四、Controller层代码实例  

     1 @Controller("assetScrapHandleController")    
     2 @RequestMapping(value="/assetScrapHandle")    
     3 public class AssetScrapHandleController  extends BaseController  {    
     4             
     5     @Resource(name=IAssetScrapHandleAction.ACTION_ID)    
     6     private IAssetScrapHandleAction assetScrapHandleAction;    
     7         
     8     @RequestMapping("/list")    
     9     @ResponseBody    
    10     public Map<String,Object> getDataList(HttpServletRequest request,CurrentPage page){    
    11         Map<String, Object> map = new HashMap<String, Object>();    
    12         Dto param = getParamAsDto(request);    
    13         String leavel = UserUtils.getLoginUserCom().getLeavel();    
    14         String orgCode = UserUtils.getUser().getUser().getOrgCode();    
    15         param.put("userLeavel", leavel);    
    16         param.put("orgCode", orgCode);    
    17         page.setParamObject(param);    
    18         CurrentPage currentPage = assetScrapHandleAction.queryForPage(page);    
    19             
    20         map.put("rows", currentPage.getPageItems());    
    21         map.put("total", currentPage.getTotalRows());    
    22             
    23         return map;    
    24     }    
    25 }    

    UserUtils.getLoginUserCom().getLeavel();执行时,返回“L0”  
    UserUtils.getUser().getUser().getOrgCode();执行时,返回“1100”  
    这些都是PowerMock的功劳!

  • 相关阅读:
    Linux系统服务
    Linux进程管理
    Linux压缩打包
    Linux输入输出
    Linux权限管理
    Linux用户管理
    Linux文件管理
    Linux-Shell
    Centos7 安装jdk1.8
    Python数据分析之路
  • 原文地址:https://www.cnblogs.com/dengshihuang/p/8178023.html
Copyright © 2020-2023  润新知