【问题标题】:Google guice module configuration for unit testing用于单元测试的 Google guice 模块配置
【发布时间】:2013-11-12 10:31:44
【问题描述】:

我正在尝试使用 google guice 进行依赖注入,但我似乎无法将所有内容连接在一起。

在我的 web.xml 中,我像这样定义了 guiceFilter 和 guiceListener:

   <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>backend.listener.GuiceConfigListener</listener-class>
</listener>

配置监听器基本上很简单:

@Override
protected Injector getInjector(){
    return Guice.createInjector(new ServletModule(), new ArtsModule());
}

此时的 ArtsModule 只有一个绑定,如下所示:

@Override
protected void configure(){
    bind(ArtsDAO.class).to(ArtsDAOGae.class);
}

然后我继续在服务类中对 ArtsDao 进行字段注入:

@Inject
private ArtsDAO artsDAO;

但是当我尝试构建我的项目(这是一个 maven 构建)时,我在 artDAO 领域得到了 NPE,这很可能是因为单元测试没有在 Web 环境中运行。

谁能建议我如何配置 guice biding 以便在单元测试期间获取它们?

谢谢

【问题讨论】:

    标签: java unit-testing maven guice-3


    【解决方案1】:

    点,

    这不是一项简单的任务,但绝对可以实现你想要的。

    首先看看https://code.google.com/p/tadedon的Tadedon项目 尤其是tadedon-guice-servlet-mock

    您将需要类似假容器之类的东西来进行测试。我的假容器还包含 Apache Shiro 集成,所以你可以把它扔掉,它看起来像:

    import com.google.inject.Guice;
    import com.google.inject.Injector;
    import com.google.inject.Key;
    import com.google.inject.Module;
    import com.xemantic.tadedon.guice.servlet.mock.FakeServletContainer;
    import com.xemantic.tadedon.guice.servlet.mock.FakeServletContainerModule;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.subject.support.SubjectThreadState;
    import org.apache.shiro.web.subject.WebSubject;
    import org.springframework.mock.web.MockHttpServletRequest;
    import org.springframework.mock.web.MockHttpServletResponse;
    
    import javax.servlet.ServletException;
    import java.io.IOException;
    import java.util.Arrays;
    public class FakeTestContainerInit {
    
        private final FakeServletContainer servletContainer;
        private final Injector internalInjector;
        private Subject internalSubject;
    
        public FakeTestContainerInit() {
            this(new Module[] {});
        }
    
        public FakeTestContainerInit(Module... modules) {
            super();
    
            modules = Arrays.copyOf(modules, modules.length + 1);
            modules[modules.length-1] = new FakeServletContainerModule();
            internalInjector = Guice.createInjector(modules);
            servletContainer = internalInjector.getInstance(FakeServletContainer.class);
        }
    
        public void start() throws ServletException, IOException {
            this.start(true);
        }
    
        public void start(boolean initializeSecurityContext) throws ServletException, IOException {
    
            getServletContainer().start();
    
            MockHttpServletRequest request = servletContainer.newRequest("GET","/");
            MockHttpServletResponse response = new MockHttpServletResponse();
    
            if(initializeSecurityContext) {
                SecurityManager scm = internalInjector.getInstance(SecurityManager.class);
                internalSubject = new WebSubject.Builder(scm, request, response).buildWebSubject();
                SubjectThreadState sts = new SubjectThreadState(internalSubject);
                sts.bind();
            } else { internalSubject = null; }
    
            getServletContainer().service(request, response);
    
        }
    
        public void stop() {
            servletContainer.stop();
        }
    
        public FakeServletContainer getServletContainer() {
            return servletContainer;
        }
    
        public <T> T getInstance(final Class<T> type) throws IOException, ServletException {
            return getServletContainer().getInstance(type);
        }
    
        public <T> T getInstance(final Key<T> key) throws IOException, ServletException {
            return getServletContainer().getInstance(key);
        }
    
        public Subject getSubject() {
            return internalSubject;
        }
    }
    

    依赖关系:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.sonatype.sisu</groupId>
            <artifactId>sisu-guice</artifactId>
        </dependency>
        <dependency>
            <groupId>com.xemantic.tadedon</groupId>
            <artifactId>tadedon-guice-servlet-mock</artifactId>
        </dependency>
    

    还有你不需要的 Apache Shiro:

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
        </dependency>
    

    您需要做的就是创建FakeTestContainerInit 并调用start()stop() 方法。此外,所有对象的创建都必须通过测试中的 FakeTestContainerInit.getInstance 方法完成。

    嗯,我用它来测试 Vaadin 应用程序,所以我不需要发送请求和检查响应。因此,您将需要实施这一点。可以通过getServletContainer().service(request, response); 完成。但我想你会明白的。希望对你有帮助。

    【讨论】:

    • 哇非常感谢朋友,shiro 是一个奖励,因为这必须在稍后阶段实现,所以再次感谢您
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多