我必须处理一些遗留代码。有一点我需要像
这样的功能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:无法访问作用域&gt;对象。我们目前不在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不会被其他任何人绑定,所以我可以创建自己的绑定来模拟它。但这似乎不太好。谁能告诉我如何正确地做到这一点?谢谢!
答案 0 :(得分:0)
我肯定建议在测试期间避免ServletModule
(集成测试除外)。另一种方法是执行ServletScopes.scopeRequest()
,这将为您创建一个虚假的请求范围。