在项目开发中,常通过junit单元测试来测试自己方法逻辑。下面主要展示,junit测试web项目的方法步骤。包括service、dao层的方法和使用Mock测试cotroller层的方法。
以下测试用例时基于公司的项目展示的,所以不便于粘贴所有的源码
junit测试环境依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.1</version>
</dependency>
junit测试service,dao层
BaseTest类介绍
@ActiveProfiles(“dev”) 设置项目启动的环境
@ContextConfiguration加载配置文件,完成springIOC注入
@ActiveProfiles("dev")
@ContextConfiguration(locations = {
"classpath:applicationContext.xml"
})
public class BaseTest extends AbstractJUnit4SpringContextTests {
public <T> T getBean(Class<T> type){
return applicationContext.getBean(type);
}
public Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
protected ApplicationContext getContext(){
return applicationContext;
}
}
具体的测试类
使用@Autowired引入dao/service包下面的对象。
public class DataMigrateScriptLogicTest extends BaseTest {
@Autowired
private DataMigrateScriptLogic dataMigrateScriptLogic;
@Test
public void test(){
dataMigrateScriptLogic.dataMigrateCommand();
}
}
遇到一个问题
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); wac == null
分析原因: ContextLoader类是web容器启动时,才会把ApplicationContext的上下文加载出来。即是通过web.xml文件中的
org.springframework.web.context.ContextLoaderListener
类来设置ApplicationContext的上下文。但是,以上的junit测试配置不能完成上下文的设置。
public static WebApplicationContext getCurrentWebApplicationContext() {
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl != null) {
WebApplicationContext ccpt = currentContextPerThread.get(ccl);
if (ccpt != null) {
return ccpt;
}
}
return currentContext;
}
如果代码中使用了
ContextLoader.getCurrentWebApplicationContext()
来获取bean,那么只要在测试用例启动时设置如下代码即可。
@Before
public void setApplication(){
MockServletContext sc = new MockServletContext("");
sc.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, "/applicationContext.xml");
ServletContextListener listener = new ContextLoaderListener();
ServletContextEvent event = new ServletContextEvent(sc);
listener.contextInitialized(event);
}
junit测试controller层
以下代码是可以用来测试controller接口。展示了post请求和get请求的简单测试。
@ActiveProfiles("dev")
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:applicationContext.xml","classpath:servlet-context.xml"})
// 无论接口调用成功或者失败,都将事物回滚
@Rollback
public class ReplenishControllerTest {
private MockMvc mockMvc;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void postTest(){
String url = "/replenish/replenishAuctionStatus";
Map<Object,Object> objectMap = Maps.newHashMap();
objectMap.put("auctionGoodId",1);
objectMap.put("success",false);
objectMap.put("cardNum","1232134");
try {
mockMvc.perform(MockMvcRequestBuilders.post(url)
.accept(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("auctionGoodId","1")
.param("success","false")
.param("cardNum","123")
.accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print()).andReturn();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void getTest(){
String url = "/replenish/get";
try {
mockMvc.perform(MockMvcRequestBuilders.get(url)
.accept(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.content("")
.accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print()).andReturn();
} catch (Exception e) {
e.printStackTrace();
}
}
}