一个通用的单元测试框架的思考和设计05-实现篇-Guice框架启动与自动注入

这篇文章将继续上一篇的问题,实现我们的iunit框架与Guice框架的整合,这个模块主要用于那些用Guice来做DI容器的项目做测试用的,包括guice框架的启动与在测试类中自动注入@Inject标注的字段

1.目标测试类的庐山真面目

package com.crazycoder2010.guice.sample;

import org.junit.Test;

import com.crazycoder2010.iunit.AbstractIUnitTestCase;
import com.crazycoder2010.iunit.GuiceStratupListener;
import com.crazycoder2010.iunit.annotation.GuiceModuleConfiguration;
import com.crazycoder2010.iunit.annotation.IUnitTestExecuteListeners;
import com.google.inject.Inject;
@GuiceModuleConfiguration(classes={MyModule.class})//标注一下当前测试用例需要加载哪几个模块
@IUnitTestExecuteListeners(value={GuiceStratupListener.class})//启动Guice监听器,这样我们@GuiceModuleConfiguraition标注的内容才能生效:)
public class ClientTest extends AbstractIUnitTestCase {
	@Inject //要用到的服务
	private Client client;
	@Test
	public void testClientGo(){
		client.go();//直接调用就可以了,框架已经帮你注入了client的值,因此不会有空指针出现了
	}
}
我们看到这个TestCase继承了我们第3节里介绍到的统一父类,然后注册了自己的IUnitTestExecuteListerner=GuiceStarupListener,然后还有个注解@GuiceModuleConfiguration,表示我们这个测试类要加载那几个Module,测试类中用到那几个服务,只要用@Inject标注一下实例变量即可--very simple

2.GuiceStartupListener类

package com.crazycoder2010.iunit;

import java.util.ArrayList;
import java.util.List;

import com.crazycoder2010.iunit.annotation.GuiceModuleConfiguration;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

/**
 * 用来启动Guice容器的Listener
 * 
 * @author Kevin
 * 
 */
public class GuiceStratupListener extends IUnitTestExecuteListenerAdapter {
	@Override
	public void prepareTestInstance(TestContext testContext) throws Exception {
		//读取Guice modules
		Class<?> c = testContext.getTestInstance().getClass();
		List<Class<? extends Module>> moduels = new ArrayList<Class<? extends Module>>();
		while(c != null){
			GuiceModuleConfiguration configuration = testContext.getTestInstance()
					.getClass().getAnnotation(GuiceModuleConfiguration.class);
			if(configuration != null){
				for(Class<? extends Module> cl : configuration.classes()){
					if(!moduels.contains(cl)){//去重
						moduels.add(cl);
					}
				}
			}
			c = c.getSuperclass();
		}
		Module[] modulesArray = new Module[moduels.size()];
		for(int i = 0; i < moduels.size(); i++){
			modulesArray[i] = moduels.get(i).newInstance();
		}
		//初始化injector
		Injector injector = Guice.createInjector(modulesArray);
		injector.injectMembers(testContext.getTestInstance());//这句是核心,让injector为当前testcase对象注入属性值,这也是为什么@Inject标注了字段名后就能直接用了的玄机所在
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Acai 是 JUnit4 和 Guice测试库,可以更容易的编写应用功能测试。主要特性:注入测试需要的助手类启动测试需要的任意的服务 运行测试之间的服务清理按照正确顺序启动多个服务 创建测试作用域绑定Acai 主要针对的是应用大型功能测试。安装<dependency>   <groupId>com.google.acai</groupId>   <artifactId>acai</artifactId>   <version>0.1</version>   <scope>test</scope> </dependency>使用 Acai 进行测试注入@RunWith(JUnit4.class) public class SimpleTest {   @Rule public Acai acai = new Acai(MyTestModule.class);   @Inject private MyClass foo;   @Test   public void checkSomethingWorks() {     // Use the injected value of foo here   }   private static class MyTestModule extends AbstractModule {     @Override protected void configure() {       bind(MyClass.class).to(MyClassImpl.class);     }   } }使用 Acai 启动服务@RunWith(JUnit4.class) public class ExampleFunctionalTest {   @Rule public Acai acai = new Acai(MyTestModule.class);   @Inject private MyServerClient serverClient;   @Test   public void checkSomethingWorks() {     // Call the running server and test some behaviour here.     // Any state will be cleared by MyFakeDatabaseWiper after each     // test case.   }   private static class MyTestModule extends AbstractModule {     @Override protected void configure() {       // Normal Guice modules which configure your       // server with in-memory versions of backends.       install(MyServerModule());       install(MyFakeDatabaseModule());       install(new TestingServiceModule() {         @Override protected void configureTestingServices() {           bindTestingService(MyServerRunner.class);           bindTestingService(MyFakeDatabaseWiper.class);         }       });     }   }   private static class MyServerRunner implements TestingService {     @Inject private MyServer myServer;     @BeforeSuite void startServer() {       myServer.start().awaitStarted();     }   }   private static class MyFakeDatabaseWiper implements TestingService {     @Inject private MyFakeDatabse myFakeDatabase;     @AfterTest void wipeDatabase() {       myFakeDatabase.wipe();     }   } } 标签:Acai

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值