我必须处理一些遗留代码。有一点我需要一个像
NewCodeAccessor.get() 它给了我一个从 Guice 获得的对象。
public class NewCodeAccessor {
@Inject
public static Provider<PageDataHandle> pageDataHandleProvider;
public static PageDataHandle get() {
return pageDataHandleProvider.get();
}
}
Guice 已提前初始化,并且请求对此类进行静态注入。
在生产代码中这工作正常,但现在我尝试测试它。PageDataHandle 是请求范围的,所以我的测试如下所示:
@Before
public void setUp() {
Injector createInjector = Guice.createInjector(new ServletModule(),
new AppModule());
}
@Test
public void testGetInjector() throws Exception {
// put it inside a callable to wrap it in a request scope, as it would
// usually be done in a request on the server
Callable<PageDataHandle> scopeRequest = ServletScopes.scopeRequest(
new Callable<PageDataHandle>() {
@Override
public PageDataHandle call() throws Exception {
PageDataHandle data = NewCodeAccessor.get();
return data;
}
}, Collections.<Key<?>, Object> emptyMap());
PageDataHandle data = scopeRequest.call();
assertTrue(data != null);
}
这仍然有效,只要 PageDataHandle 或其依赖项不为请求参数请求注入:
@Inject @RequestParameters Map<String, String[]> requestParameters
在这里,我得到一个 OutOfScope 异常:com.google.inject.ProvisionException:Guice 配置错误:
1) 自定义提供程序中的错误,com.google.inject.OutOfScopeException:无法访问作用域 > 对象。要么我们当前不在 HTTP Servlet 请求中,要么您可能忘记 > 应用 com.google.inject.servlet.GuiceFilter 作为该请求的 servlet 过滤器。
我试图用这样的东西添加我自己的测试模块:
bind(new TypeLiteral<Map<String, String[]>>() {
}).annotatedWith(com.google.inject.servlet.RequestParameters.class)
.toInstance(parameters);
但这不起作用,因为 RequestParameters 已经被 ServletRequest 绑定。
我可以做的是:我在为我的测试创建的注入器中省略了 ServletModule,并将 RequestScope 绑定到我自己的自定义范围。然后 RequestParameters 不会被其他任何人绑定,所以我可以创建自己的绑定来模拟它。但这似乎不太好。谁能告诉我如何正确地做到这一点?谢谢!