Spring 对于单元测试来说,我感觉还是挺方便的。
我们可以用maven来构建项目,这样对于包的依赖就交给maven处理。
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.myapp</groupId> <artifactId>guiapp</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>logGUIApp</artifactId> <packaging>jar</packaging> <name>my app </name> <description>log in interface</description> <dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-atinject_1.0_spec</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.1.1.RELEASE</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> </dependencies> </project>
大概就这么一个POM 文件
接下来我们还是关注如何使用Spring做单元测试。
还是来一个AbstractSpringTestCase 母类。
import java.io.File;
import javax.annotation.Resource;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* This class provides convenient afterTestClass and beforeTestClass methods from Spring Framework which subclasses can
* override to perform actions once per test class.
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractSpringTestCase
extends AbstractJUnit4SpringContextTests {
protected static File basedir = new File( System.getProperty( "basedir", "." ) );
protected static File builddir = new File( basedir, "target" );
@Resource
protected ApplicationContext applicationContext;
/**
* This allows eclipse and maven to have the same basedir
*/
@BeforeClass
public static void beforeBaseClass() {
System.setProperty( "basedir", System.getProperty( "basedir", "." ) );
System.setProperty( "derby.system.home", System.getProperty( "derby.system.home", "./target" ) );
}
}
大家看到这个类的一个注解 @RunWith 也就是JUnit使用了指定的类来启动测试
然后就交给SpringJUnit4ClassRunner 了。这个类 会寻找你的配置文件,这里我更喜欢用注解来指定
请看一个简单测试类。
@ContextConfiguration(locations = { "classpath:/com/myapp/guiapp/jdbc/test/applicationContext.xml" })
public class JdbcTest
extends AbstractSpringTestCase {
@Inject
private MyAppJdbcConnectionFactory myAppJdbcConnectionFactory;
@Inject
private Storage storage;
@Inject
private TcpServerTask tcpServerTask;
private int port;
@Before
public void before() {
port = tcpServerTask.getPort();
}
@BeforeClass
public static void beforeClass()
throws Exception {
System.setProperty( "javax.net.ssl.keyStore", basedir + "/target/etc/mc.ks" );
System.setProperty( "javax.net.ssl.trustStore", basedir + "/target/etc/mc.ts" );
System.setProperty( "javax.net.ssl.keyStorePassword", "changeit" );
System.setProperty( "javax.net.ssl.trustStorePassword", "changeit" );
}
@Test
public void testJdbcDirectAccessToStorage()
throws Exception {
Connection connection = null;
try {
// just enough to get JDBC connect direct to storage with same jvm, ie no tcpserver involved
String goodUrl = "jdbc:myapp:DummyTable";
String badUrl = "jdbc:myapp:DummyTableBad";
try {
connection = myAppJdbcConnectionFactory.getConnection( badUrl, "", "", null );
Assert.fail( "Able to create connection with invalid URL" );
}
catch ( DataProviderException e ) {
}
connection = myAppJdbcConnectionFactory.getConnection( goodUrl, "", "", null );
Assert.assertNotNull( connection );
}
finally {
ConnectionUtils.closeQuietly( connection );
}
}
}
@ContextConfiguration 指定了此测试类使用的bean配置文件。
在这个文件中,我们就可以定义测试需要的一些bean
<beans default-lazy-init="true" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <import resource="classpath:com/myapp/jdbc/applicationContext.xml" /> <bean id="tcpServerTask" class="com.myapp.transport.server.internal.TcpServerTask"> <property name="enableSSL" value="false" /> </bean> </beans>
然后就使劲折腾吧。