Spring在J2EE开发中已经应用得十分广泛,在进行实际开发时,往往需要对Service和DAO层进行单元测试。本文基于Spring框架,使用Jnit4进行单元测试。
项目结构主要包括:DAO层接口和实现,Service层接口和实现,配置文件及测试用例。
主要jar包通过maven进行管理,pom.xml关键配置信息如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>mall</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springmvc Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <!-- spring版本号 --> <spring.version>3.2.5.RELEASE</spring.version> <!-- mybatis版本号 --> <mybatis.version>3.2.5</mybatis.version> <!-- log4j日志文件管理包版本 --> <slf4j.version>1.6.6</slf4j.version> <log4j.version>1.2.9</log4j.version> </properties> <dependencies> <!-- spring核心包 --> <!-- springframe start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- springframe end --> <!-- junit测试包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>springmvc</finalName> </build> </project>
DAO层及实现示例代码:
package com.mall.dao;
public interface TestDAO {
public void save(String str);
}
package com.mall.dao.impl;
import java.util.logging.Logger;
import com.mall.dao.TestDAO;
public class TestDAOImpl implements TestDAO{
private Logger logger = Logger.getLogger(TestDAO.class.getName());
public void save(String str) {
logger.info("This is DAO args:"+str);
}
}
Service层及实现:
package com.mall.service;
public interface TestService {
public void save(String str);
}
package com.mall.service.impl;
import java.util.logging.Logger;
import com.mall.dao.TestDAO;
import com.mall.service.TestService;
public class TestServiceImpl implements TestService{
private Logger logger = Logger.getLogger(TestServiceImpl.class.getName());
private TestDAO dao;
public void save(String str) {
logger.info("Service entered arg:"+str);
str = str + " has been modified";
dao.save(str);
}
public void setDao(TestDAO dao) {
this.dao = dao;
}
}
spring容器配置文件:spring-test.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="TestService" class="com.mall.service.impl.TestServiceImpl"> <property name="dao" ref="TestDAO"></property> </bean> <bean id="TestDAO" class="com.mall.dao.impl.TestDAOImpl"> </bean> </beans>
下面开始编写测试用例,在进行测试之前,需要统一加载配置文件,并提供产生Bean的方法,考虑使用以下基础测试类来提供公共测试环境:
package com.mall.util;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlpath;
public UnitTestBase() {}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
springXmlpath = "classpath*:spring-*.xml";
}
try {
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
return (T)context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
protected <T extends Object> T getBean(Class<T> clazz) {
try {
return context.getBean(clazz);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
在书写测试用例时,使用Junit4提供的注解:
package mall.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.mall.service.impl.TestServiceImpl;
import com.mall.util.UnitTestBase;
@RunWith(BlockJUnit4ClassRunner.class)
public class TestInj extends UnitTestBase{
public TestInj(){
super("classpath:spring-test.xml");
}
@Test
public void test(){
TestServiceImpl service = super.getBean("TestService");
service.save("Idiot.");
}
}
将测试用例作为Junit TestCase运行,将看到控制台输出以下内容:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
十一月 17, 2015 7:37:04 下午 com.mall.service.impl.TestServiceImpl save
INFO: Service entered arg:Idiot.
十一月 17, 2015 7:37:04 下午 com.mall.dao.impl.TestDAOImpl save
INFO: This is DAO args:Idiot. has been modified
表明Service层对DAO层的调用测试通过。
实际开发中,Service层往往具有更为复杂的业务逻辑,而DAO层通常仅负责与数据库进行交互,使用这种测试方法能较好地完成业务层和数据库操作层的单元测试。