gpt4 book ai didi

java - 使用 Guice Servlet 测试项目 : How to bind out-of-scope RequestScoped instances?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:42:57 26 4
gpt4 key购买 nike

我们有一个使用 Guice 和 Guice Servlet 扩展实例化的 Java 网络应用程序。该应用程序还包括同样由 Guice 实例化的 Quartz 作业。我想为这些工作编写单元测试。

作业类依赖于我们生产代码中的其他类,这些类需要 Provider<HttpServletRequest> .在生产设置中,作业可以由 Guice 成功实例化,并且作业按预期工作,因为它们从不调用其协作者的任何代码来触发 get。在 servlet 请求提供者上。这样一个get调用会失败,因为作业是由某个工作线程执行的,而不是作为对 servlet 的 HTTP 请求的一部分。

现在我的问题是如何在 JUnit 测试中设置 Guice,以便获得相同的行为,即可以实例化作业类,但所有尝试都使用任何范围外的 @RequestScoped对象会失败。


有两种直接的解决方案,但它们对我不起作用。

如果我不绑定(bind)任何HttpServletRequest ,尝试在测试设置中实例化作业时出现错误:

com.google.inject.CreationException: Guice creation errors:

1) No implementation for javax.servlet.http.HttpServletRequest was bound.
while locating com.google.inject.Provider<javax.servlet.http.HttpServletRequest>

另一方面,如果我只是绑定(bind)模拟实例,例如与

@Override
protected void configure() {
bind(HttpServletRequest.class).toInstance(mock(HttpServletRequest.class));
}

然后可以实例化作业,但如果作业使用 servlet 请求实例,我将不再收到测试错误。那么我如何创建一个绑定(bind),以便 Guice 能够实例化提供者,但对提供者的任何使用都会失败?

最佳答案

经过几次尝试,我发现了如何在测试模块中绑定(bind) @RequestScoped 对象:

@Override
protected void configure() {
bindScope(RequestScoped.class, ServletScopes.REQUEST);

bind(ServletRequest.class).toProvider(unusableProvider(ServletRequest.class)).in(RequestScoped.class);
bind(HttpServletRequest.class).toProvider(unusableProvider(HttpServletRequest.class)).in(RequestScoped.class);
bind(ServletResponse.class).toProvider(unusableProvider(ServletResponse.class)).in(RequestScoped.class);
bind(HttpServletResponse.class).toProvider(unusableProvider(HttpServletResponse.class)).in(RequestScoped.class);
}

private static <T> Provider<T> unusableProvider(final Class<T> type) {
return new Provider<T>() {
@Override
public T get() {
throw new IllegalStateException("Unexpected call to provider of " + type.getSimpleName());
}
};
}

测试从不进入请求范围(即没有调用 ServletScope.scopeRequest),因此在测试中所有获取 RequestScoped 对象的尝试都会导致与生产中的错误完全相同:

com.google.inject.ProvisionException: Guice provision errors:

1) Error in custom provider, com.google.inject.OutOfScopeException: Cannot access scoped object. Either we are not currently inside an HTTP Servlet request, or you may have forgotten to apply com.google.inject.servlet.GuiceFilter as a servlet filter for this request.

绑定(bind)一个“不可用的提供者”实际上并不是必需的——我只是把它作为一个额外的安全网。这意味着该解决方案也适用于未显式绑定(bind)但使用 @RequestScoped 注释并由 Guice 自动发现的类。

关于java - 使用 Guice Servlet 测试项目 : How to bind out-of-scope RequestScoped instances?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31074004/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com