I have to deal with some legacy code. There is one point where I need a function like
NewCodeAccessor.get() which gives me an object that is obtained from Guice.
public class NewCodeAccessor {
@Inject
public static Provider<PageDataHandle> pageDataHandleProvider;
public static PageDataHandle get() {
return pageDataHandleProvider.get();
}
}
Guice is initialized earlier and a static injection on this class is requested.
In production code this works fine, but now I try to test it. PageDataHandle is request scoped, so my test looks like this:
@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);
}
This still works, as long as PageDataHandle or it's dependencies doesn't requests a injection for the request parameters:
@Inject @RequestParameters Map<String, String[]> requestParameters
Here I get an OutOfScope Exception: 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.
I tried to add my own test module with something like this:
bind(new TypeLiteral<Map<String, String[]>>() {
}).annotatedWith(com.google.inject.servlet.RequestParameters.class)
.toInstance(parameters);
But this doesn't work because RequestParameters is already bound by ServletRequest.
What I could do is the following: I leave out the ServletModule in the injector I create for my test and bind RequestScope to my own, custom scope. Then RequestParameters wouldn't be bound by anyone else, so I could create my own binding to mock that. But that doesn't seem nice. Could anyone tell me how to do this properly? Thanks!