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层通常仅负责与数据库进行交互,使用这种测试方法能较好地完成业务层和数据库操作层的单元测试。