0

我正在尝试使用 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 投标,以便在单元测试期间拾取它们?

谢谢

4

1 回答 1

2

点,

这不是微不足道的任务,但绝对可以实现您想要的。

首先看看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);. 但我想你会明白的。希望它会帮助你。

于 2013-11-12T12:00:49.547 回答