dubbo应用程序的单元测试环境搭建(springtest,powermock,mockito)(一)

最近,项目中频繁用到dubbo,而且java工程用引用了几十个关联系统的服务(如用户认证,基础服务,客户平台)。这些服务都是dubbo服务,对我们仅提供了一个接口,服务通过zookeeper注册,并给我们提供服务。我们的项目都是基于spring的。spring集成dubbo,就可以对这些外部服务进行注入和使用了。

    但是对于单元测试来说却出现了难题:领域模型的测试不是问题,主要都是自己的代码,加上一些mock就可以轻松测试;但是如果我想测试应用服务层(使用外部服务最多的地方),很多情况下就需要启动spring环境,而这样就需要加载外部系统的服务了。问题是外部的服务给我们的jar包中,只有服务的接口。启动时如果按照正常开发环境的配置加载spring context,那么明显是依赖了外部环境,如果没有启动zookeeper或者本机不联网,抑或是关联系统没有启动,spring context加载将会失败,这是单元测试的忌讳。如果使用专门的单元测试的spring配置文件,去掉外部关联系统的consumer配置,启动会直接失败,更别提测试了。

 还有写其他问题,如测试静态方法,私有方法;mock框架与springtest如何集成。spring的aop代理类如何mock一些默认的实现,测试数据库如何选择。总之问题超多。好吧,该进入正题了。

   1.测试静态类,私有方法的问题

        简单一句话,用powermock。powermock可以做到修改字节码而改变类的行为,这不多说了,大家自己搜一下,官网上例子通俗易懂。目前我在maven中的关于powermock,mockito的依赖是这样加入的:

   

<dependency>
				<groupId>org.powermock</groupId>
				<artifactId>powermock-api-mockito</artifactId>
				<version>1.6.6</version>
			</dependency>

			<dependency>
				<groupId>org.mockito</groupId>
				<artifactId>mockito-all</artifactId>
				<version>1.10.19</version>
			</dependency>
			<dependency>
				<groupId>org.powermock</groupId>
				<artifactId>powermock-module-junit4</artifactId>
				<version>1.6.6</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>org.powermock</groupId>
				<artifactId>powermock-module-junit4-rule-agent</artifactId>
				<version>1.6.6</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>org.powermock</groupId>
				<artifactId>powermock-module-junit4-rule</artifactId>
				<version>1.6.6</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>org.jacoco</groupId>
				<artifactId>org.jacoco.agent</artifactId>
				<classifier>runtime</classifier>
				<version>0.7.9</version>
				<scope>test</scope>
			</dependency>


最后的话这个jacoco不是mock的依赖,是一个测试覆盖率的插件。也推荐一下给大家用,哈哈。

    2.powermock与springtest配合使用的问题

        第一个问题解决了,不错!第二个问题就来了。spring标准的Runner是SpringJUnit4ClassRunner,如果用这个Runner,那么powermock的@PrepairForTest就没法使用了(也就是静态mock,私有方法mock的关键),因此如果想使用静态和私有方法mock就必须使用用Powemock的Runner,但是又如何启动spring context呢?

     经过一些查找,终于解决了这个问题,方法就是用powermock的代理, 在测试类上加上这样的注解:

     

@PowerMockIgnore({"java.lang.management.*","javax.management.*","javax.xml.*","org.xml.sax.*","org.apache.xerces.*","org.w3c.*"})
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:META-INF/spring/test-spring.xml")

Runner使用PowerMockRuner(就是RunWith注解的值);使用powermock提供的代理来使用SpringJUnit4ClassRunner;@PowerMockIgnore的作用是忽略一些powermock使用的classloader无法处理的类,不使用的话,启动用例就会报错。

classpath:META-INF/spring/test-spring.xml 是单元测试专门的spring配置文件,和域代码使用的配置有些不同。这个文件我放在/test/resources/spring/目录下。

  到此,一个基于PowerMock,springtest和Mockito的基本配置就都弄完了。好了,第一部分先到这里。待续

猜你喜欢

转载自blog.csdn.net/yys79/article/details/66472797