首页 > 解决方案 > 如何使用 Guice 注入 JUnit 集成测试

问题描述

我正在做一个项目,我需要对我的 Web 服务进行一些集成测试。该应用程序使用 guice 3.0 进行依赖注入。对于我的单元测试,我可以使用自定义的 junit 运行器 ( https://github.com/sfragis/GuiceJUnitRunner ) 来注入测试类。不幸的是,这种方法不适用于集成测试。guice 模块作为服务器启动的一部分被初始化,所以我不能使用为每个测试手动初始化 guice 模块的运行器。

我过去解决这个问题的方法是创建一个带有静态字段的类来存储 guice 注入器。在引导过程中,我会抓取注入器实例并使用它来设置类字段。就像是:

public void contextInitialized(final ServletContextEvent event)
    {
        super.contextInitialized(event);
        final ServletContext context = event.getServletContext();
        ...
        Injector injector = processor.process(modules);
        final String holderClass = "com.guice.GuiceHolder"
        if(holderClass!=null){
            final Class clazz = Thread.currentThread().getContextClassLoader().loadClass(holderClass.trim());
            Field f=clazz.getDeclaredField("injector");
            if(f!=null && Modifier.isStatic(f.getModifiers()) && Modifier.isPublic(f.getModifiers())){
                f.set(clazz,injector);
            }else{
                logger.info("Guice holder '"+clazz.getName()+"' does not contain a public static 'injector' field");
            }
        }
        else{
            logger.warn("No guice holder specified");
        }
}

然后在我的测试中,我会做类似的事情:

public class MyTest
{
    @Inject
    public String host;

    @Before
    public void setup()
    {
        com.guice.GuiceHolder.injector.injectMembers(this);
    }
  
    @Test
    public void testSomething()
    {
        HttpURLConnection http = (HttpURLConnection)new URL("http://" + host +":8080/hello/other/world").openConnection();
        http.connect();
        assertThat("Response Code", http.getResponseCode(), is(HttpStatus.OK_200));
    }
}

它可以工作,但它很复杂,并且保存这样的注入器实例看起来像是代码异味。我确信必须有一种更清洁的方法来处理这个问题,但到目前为止,我还没有想出任何其他有效的方法。有谁知道在这种情况下处理依赖注入的更好方法?我目前的方法真的那么糟糕还是我想多了?

标签: javaintegration-testingjunit4guiceresteasy

解决方案


推荐阅读