您的位置:首页 > 编程语言 > Java开发

[单元测试]PowerMock+SpringMVC整合并测试Controller层方法(一)

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

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

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

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
</dependency>

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
</dependency>
二、单元测试基类

import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

@RunWith(PowerMockRunner.class)  //使用PowerMockRunner运行时
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)  //委派给SpringJUnit4ClassRunner
@ContextConfiguration (locations={"classpath:META-INF/app_config/context/context-*.xml"}) //加载配置文件
@Transactional
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@PowerMockIgnore({"javax.management.*"}) //忽略一些mock异常
public class BaseJunit4 {

}

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

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

三、单元测试类

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.util.ReflectionTestUtils;

import com.asset.action.IAssetScrapHandleAction;
import com.asset.controller.AssetScrapHandleController;
import com.framework.core.persistence.pagination.CurrentPage;

@PrepareForTest({OrgUtils.class,UserUtils.class})
public class ScrapAssetApplyActionImplTest extends BaseJunit4{
@InjectMocks@Autowired
private static AssetScrapHandleController controller;

@Resource(name=IAssetScrapHandleAction.ACTION_ID)
private IAssetScrapHandleAction aSHAction;

@Before
public  void befor(){
//依赖注入相应的action
ReflectionTestUtils.setField(controller, "assetScrapHandleAction", aSHAction);
}

@Test
public void testCreateHandleNum() {
Map map = new HashMap();
PowerMockito.mockStatic(OrgUtils.class);PowerMockito.mockStatic(UserUtils.class);

//自定义模拟静态方法返回的对象1
OrganizationBO bo = new OrganizationBO();
bo.setLeavel("L0");
PowerMockito.when(UserUtils.getLoginUserCom()).thenReturn(bo);

//自定义模拟静态方法返回的对象2
UserBO userbo = new UserBO();
userbo.setOrgCode("1100");
LoginUser loginUser = new LoginUser(userbo);
PowerMockito.when(UserUtils.getUser()).thenReturn(loginUser);

//模拟请求
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("time", "2016-01-01");
CurrentPage page = new CurrentPage();
page.setRows(25);
map = controller.getDataList(request, page);
boolean actual = true;
assertEquals(Integer.valueOf(map.get("total").toString())>=1, actual);
}
}
对Controller测试时,还需要由Controller层中的Action去执行相应的业务代码,对于Action的依赖注入就可以非常方便的使用ReflectionTestUtils.setField(controller,"assetScrapHandleAction",aSHAction)(非常重要),将aSHAction注入到controller层中的属性名为assetScrapHandleAction中

@PrepareForTest({OrgUtils.class,UserUtils.class}) 注解一定要放到类上,或者基类上也可以,千万不能放到方法上。如果在方法上,会导致每执行一次test方法,都会委托SpringJUnit4ClassRunner去加载一次上下文配置,将直接导致内存耗尽。

四、Controller层代码实例

@Controller("assetScrapHandleController")
@RequestMapping(value="/assetScrapHandle")
public class AssetScrapHandleController  extends BaseController  {

@Resource(name=IAssetScrapHandleAction.ACTION_ID)
private IAssetScrapHandleAction assetScrapHandleAction;

@RequestMapping("/list")
@ResponseBody
public Map<String,Object> getDataList(HttpServletRequest request,CurrentPage page){
Map<String, Object> map = new HashMap<String, Object>();
Dto param = getParamAsDto(request);
String leavel = UserUtils.getLoginUserCom().getLeavel();
String orgCode = UserUtils.getUser().getUser().getOrgCode();
param.put("userLeavel", leavel);
param.put("orgCode", orgCode);
page.setParamObject(param);
CurrentPage currentPage = assetScrapHandleAction.queryForPage(page);

map.put("rows", currentPage.getPageItems());
map.put("total", currentPage.getTotalRows());

return map;
}
}
UserUtils.getLoginUserCom().getLeavel();执行时,返回“L0”

UserUtils.getUser().getUser().getOrgCode();执行时,返回“1100”

这些都是PowerMock的功劳!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐