1

我必须处理一些遗留代码。有一点我需要一个像

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 不会被其他任何人绑定,所以我可以创建自己的绑定来模拟它。但这似乎不太好。谁能告诉我如何正确地做到这一点?谢谢!

4

1 回答 1

0

我肯定会建议避免ServletModule在测试期间(集成测试除外)。另一种方法是ServletScopes.scopeRequest()为您创建一个虚假的请求范围。

于 2013-07-08T16:08:55.763 回答