Spring2.5Test测试
上一篇介绍了把ibatis搞到项目中来,现在是时候验证一下代码是否正确的时候了,我们在小项目里采用的是Spring2.5自带的测试框架,为什么?因为他提供了一系列测试的扩展,如测试类只要继承一下AbstractTransactionalJUnit38SpringContextTests类,spring框架的启动和管理都交给测试框架去管理,这个基类还提供了事务管理的功能,在测试中可以对莫个用例进行控制,执行完毕后数据库又回滚到测试执行的状态,从而达到即完成了测试,又保证测试数据即使清理的问题,来看一下我们的执行
1)测试类的存放和命名
目前所有的测试类统一放置在src/test/java中,测试目前处于业务逻辑层,因为业务逻辑层会调用dao层,所以不对dao层做单独测试,测试类的包结构层次和java源文件保持严格一致,如com.taobao.top.coreapp.service.user.impl.UserInfoServiceImpl类的测试代码为com.taobao.top.coreapp.service.user.impl.UserInfoServiceImplTest,测试方法采用test+方法名的方式,如testGetUserInfoById(),对要进行事物控制的测试用例用spring的@Transactional标注注解,这样spring测试框架在执行时会在测试用例开始时开启事物,而在测试用例结束时把当前事物回滚
2)拉出我们Service层的接口方法run一把,验证一下我们前两篇里的配置是否正确--这里我们还没有把dbunit拉如进来,以下的例子还只是验证框架的集成是否Ok
@Transactional
public void testCreateUserInfo() {
UserInfo userInfo = new UserInfo();
userInfo.setName("zhangsan");
userInfo.setPassword("111111");
userInfo.setNick("张三");
try {
userInfoService.createUserInfo(userInfo);
logger.info(userInfo);
Assert.assertTrue(userInfo.getId() > 0);
} catch (CoreAppBizException e) {
Assert.fail("创建用户测试用例失败");
}
}
跑了一把,失败了,后台报错
java.lang.NoSuchMethodError: org/springframework/core/annotation/AnnotationUtils.findAnnotationDeclaringClass(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Class;
at org.springframework.test.context.TestContext.retrieveContextLocations(TestContext.java:143)
at org.springframework.test.context.TestContext.<init>(TestContext.java:108)
at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:103)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:102)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:79)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:67)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:521)
at org.junit.internal.requests.ClassRequest.buildRunner(ClassRequest.java:33)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:28)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:26)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:34)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:24)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:445)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
找不到方法,这个是为什么呢,这个问题迷惑了我很久,后来找到原因了
大家知道spring的测试框架是spring2.5里的内容,所以当时我把spring里的依赖版本从2.0改成了2.5.4,spring的测试框架版本也是2.5.4,为什么还找不到呢?
通过maven的dependency 视图我搜索了一下spring,结果惊奇的发现还有spring-core2.0,spring-beans2.0这样的依赖,这些依赖从哪里来的?原来是maven自动生成的那个个框架中使用的是spring2.0的版本,虽然我们手动的把spring的版本该改成2.5了,但是这些jar包里的依赖还在,怎么办呢?在pom文件里把这些依赖排除一下就行了
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.0.11.2</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
</exclusion>
</exclusions>
</dependency>
果然,排除后问题解决了,单元测试也跑起来了,框架没问题了,兴奋的去数据库去查一下数据,结果又悲剧了,中文乱码了,呵呵,这个也纠结过一阵子,以下是分析过程
a)先前都是在windows下编程,windows下的mysql目录中有个my.ini文件,改一下里面的编码集就行了,Ubuntu上的在哪里呢
google,baidu,都用上了,原来linux系统下是在 /etc/mysql/my.cnf,呵呵,换了个马甲我一样能找到你~
b)修改一下编码集
要改动3处地方,分别找到[client],[mysqld],[mysqldump]在这三个元素的下面分别加一句话default-character-set=utf8保存退出,重启一下mysql服务就ok了,可怜的中文终于存放进去了,遇到类似问题的时候多数是这些个参数没设置导致的,可以用命令行登录系统,通过输入status看一下编码集合是否都改动成utf-8了(默认是litin1),如图,设置后的编码都是UTF8
总结:
maven是个双刃剑,一方面会带来很大的便利性,一部到位,你不用去了解太多的东西,但是这也是他的问题所在,特别是对于间接依赖,不了解他的整个流程,很难去解决问题,问题出来的时候多看看报错信息,尝试从报错信息中找出一些答案,然后验证自己的想法,然后google,乱码的问题也是很经常的问题,对于这种编码经验就是统一编码,从数据库到jsp,到程序源码,jsp,vm,ftl,邮件所有都utf8一般都是不会出问题的,utf8一统天下,呵呵