web单元测试经常会在执行前准备一些数据
执行完毕后删除这些数据 如下伪代码
这很烦!
采用jdbcTemplate或一些其他的方法也很烦
毕竟要写一堆无关紧要的代码
[b]先看我们改进后的效果[/b]
BeforeMethod 是在执行测试方法前准备数据
AfterMethod 来清理数据
其value值是一些 sql语句
会写sql就ok了 不用其他知识
[b]再来看看具体实现[/b]
很简单扩展一下spring 提供的TestExecutionListener接口就行了
扩展后的类
实际上是将jdbcTemplate转移了个位置而已
[b]这个PreparedDataTestExecutionListener怎么用呢 [/b]
接着看代码
这样你的testcase只要继承JUnit4TestCase就可以使用BeforeMethod和AfterMethod了
[b]附上BeforeMethod和AfterMethod[/b]
执行完毕后删除这些数据 如下伪代码
public void testFindUser(){
jdbcTemplate.insert('insert into user...');
jdbcTemplate.insert('insert into user...');
User u = userManager.findUser("....");
Assert();
jdbcTemplate.delete();
}
这很烦!
采用jdbcTemplate或一些其他的方法也很烦
毕竟要写一堆无关紧要的代码
[b]先看我们改进后的效果[/b]
BeforeMethod 是在执行测试方法前准备数据
AfterMethod 来清理数据
其value值是一些 sql语句
public class MessageManagerTest extends JUnit4TestCase {
@Autowired
MessageManager messageManager;
@Test
@BeforeMethod({
"insert into sns_user(id, email,password, nickname, enabled) values ('10','100@justel.com.cn','password','haha', 1);",
"insert into sns_user(id, email,password, nickname, enabled) values ('11','101@justel.com.cn','password','haha2', 1);"
})
@AfterMethod({"delete from sns_message", "delete from sns_user"})
public void send(){
Message msg = new Message();
try {
messageManager.send(msg);
} catch (UserNotExistException e) {
Assert.fail();
}
int count = simpleJdbcTemplate.queryForInt("select count(*) from sns_message where id = ?", msg.getId());
Assert.assertEquals(1, count);
}
}
会写sql就ok了 不用其他知识
[b]再来看看具体实现[/b]
很简单扩展一下spring 提供的TestExecutionListener接口就行了
public interface TestExecutionListener {
void prepareTestInstance(TestContext testContext) throws Exception;
//测试前执行
void beforeTestMethod(TestContext testContext) throws Exception;
//测试后执行
void afterTestMethod(TestContext testContext) throws Exception;
}
扩展后的类
public class PreparedDataTestExecutionListener extends AbstractTestExecutionListener {
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
BeforeMethod beforeMethod = testContext.getTestMethod().getAnnotation(BeforeMethod.class);
if(beforeMethod != null){
executeBeforeMethod(testContext, beforeMethod);
}
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
AfterMethod afterMethod = testContext.getTestMethod().getAnnotation(AfterMethod.class);
if(afterMethod != null){
executeAfterMethod(testContext, afterMethod);
}
}
/**
* 准备数据
*/
protected void executeBeforeMethod(TestContext testContext, BeforeMethod beforeMethod){
DataSource dataSource = (DataSource)testContext.getApplicationContext().getBean("dataSource");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String[] sqls = beforeMethod.value();
for (String sql : sqls) {
jdbcTemplate.execute(sql);
}
}
/**
* 清理数据
*/
protected void executeAfterMethod(TestContext testContext, AfterMethod afterMethod){
DataSource dataSource = (DataSource)testContext.getApplicationContext().getBean("dataSource");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String[] sqls = afterMethod.value();
for (String sql : sqls) {
jdbcTemplate.execute(sql);
}
}
}
实际上是将jdbcTemplate转移了个位置而已
[b]这个PreparedDataTestExecutionListener怎么用呢 [/b]
接着看代码
@ContextConfiguration(locations = { "classpath:/application-test.xml" })
@TestExecutionListeners({PreparedDataTestExecutionListener.class})
public class JUnit4TestCase extends AbstractTransactionalJUnit4SpringContextTests{
}
这样你的testcase只要继承JUnit4TestCase就可以使用BeforeMethod和AfterMethod了
[b]附上BeforeMethod和AfterMethod[/b]
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BeforeMethod {
String[] value() default {};
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AfterMethod {
String[] value() default {};
}