经常会遇到一个问题,在Eclipse中执行JUnit测试是正常的,但使用Mave的test命令测试是失败的。在Maven中执行测试是使用Surefire插件进行的,所以需要在pom.xml文件中对Surefire插件进行设置。
首先对Surefire插件进行如下设置,基本上可以解决大多数这个问题:
Surfire 2.14以上版本,forkMode配置项被废弃,使用下面的配置进行替代:
昨天我执行Spring Dao的测试,中间使用jdbc:initialize-database通过自动导入sql文件的方式初始化数据库的数据,因为文件中有中文出现了乱码,造成初始化失败。另外,默认情况下会发现执行mvn test命令的结果里面包含有很多乱码,可以在argLine中指定文件的编码。偶尔也会有执行mvn test造成内存溢出的错误,也可以在argLine中进行配置,内容如下:
其实Eclipse下面的JUnit和mvn test的环境有很多是不一样的,比如执行JUnit正常,但mvn test会提示找不到某些资源文件,这是因为所有的非java文件都必须放到resources文件夹中,项目资源文件放在src/main/resources中,测试资源文件放在src/test/resources文件夹中。这一点一定要特别注意,有时候在webapp项目中进行测试的时候,需要WEB-INF文件夹放在Class Path中,配置如下:
其他相关的目录如果也想加入到Class Path中的话方法也是类似的。
以上可以说能够解决95%以上的上述问题,但昨天我遇到一个非常奇葩的情况,简单来说有个Maven项目除了一个主pom.xml文件之外,包含两个子模块moduleA和moduleB,结构如下:
main |-- ModuleA |-- ModuleB pom.xml
ModuleB依赖ModuleA,在Eclipse中对ModuleB进行单元测试正常,但对ModuleB执行mvn test命令的时候总是出现NullPointerException,不过我对出现NullPointerException异常的变量进行日志输出或调试的时候是有值的,非常奇怪。后来经过近两个小时的调试和排查发现原来ModuleB中测试的类中用到了ModuleA中类的某个方法,而这个方法是新增加的,并且ModuleA没有install,在Eclipse中默认会将ModuleA放入到环境变量中,所以不会出错。但执行mvn test的时候并不会将依赖的项目放入到ClassPath中,所以出现了错误。不过这个错误也的确怪异了一些,最后先将ModuleA使用mvn install之后,在对ModuleB进行mvn test就可以通过测试了。
参考资料:
JUnit tests pass in Eclipse but fail in Maven Surefire
Spring JUnit test keeps return nullpointerexception on my service class
spring junit testing