【问题标题】:How to mock an Authenticator in play framework with guice injections?如何使用 guice 注入在游戏框架中模拟 Authenticator?
【发布时间】:2015-05-17 22:10:46
【问题描述】:

我有一个带有经过身份验证的路由的播放应用程序。我实现了一个身份验证器,将用户存储到弹性搜索中。我的控制器中的安全方法使用@Security.Authenticated 注释进行了注释。对于我使用 mockito 进行的单元测试,我想模拟这个类,但我不知道该怎么做。

我在 Guice 中使用 DI。所以我尝试了这种方法:

  1. 开发一个AuthenticatorWrapper如下:

    public class AuthenticatorWrapper extends Security.Authenticator {
    
        private Authenticator authenticator;
    
        @Override
        public String getUsername(Http.Context ctx) {
            return authenticator.getUsername(ctx);
        }
    
        @Override
        public Result onUnauthorized(Http.Context ctx) {
            return authenticator.onUnauthorized(ctx);
        }
    
        @Inject
        public void setAuthenticator(Authenticator authenticator) {
            this.authenticator = authenticator;
        }
    }
    

    这个类有一个Authenticator作为参数,应该是Guice在应用启动时注入的。

  2. 我开发了一个 guice 模块,定义了类 Authenticator.classMyCustomAuthenticator.class 的绑定

  3. 我的安全路由标注了@Security.Authenticated(AuthenticatorWrapper.class)

在我的测试中,我可以轻松地提供 MyCustomAuthenticator 类的模拟,我创建模拟,定义测试范围 guice 模块,并定义从 Authenticator.class 到模拟的绑定。

我认为这应该可行,但事实并非如此。无论是在正常运行时还是在我的测试中,绑定似乎都不起作用。我有来自包装器的nullPointerException,当:Authenticator 参数不是由 Guice 注入的。

所以我的问题是:

  • Authenticator 是从 Guice 注入我的验证器的好方法吗?也许有一种更简单的方法可以将 play Authenticator 注入 Guice 的注释中?
  • Guice 没有将 Authenticator 注入到我的包装器中是否正常? [EDIT -> 是的,因为注释手动实例化了我的对象并且不使用 guice。我说的对吗?]
  • 我可以通过将MyCustomAuthenticator 直接设置到注释中来简化我的应用程序,但是如何在我的测试中模拟这个身份验证器?

谢谢:)

【问题讨论】:

  • 你确定 Guice 被用来创建 AuthenticatorWrapper 吗? NPE 另有暗示。一种检查方法是改用构造函数注入(这会更好 iMHO,因为 authenticator 字段可以是最终的

标签: java playframework playframework-2.0 guice guice-3


【解决方案1】:

A 找到了解决方法。我只是使用了 Play framework 2.4 提供的访问方法,因为它完全集成了 Guice。这是我的身份验证包装类:

public class AuthenticatorWrapper extends Security.Authenticator {

    private final Security.Authenticator authenticator;

    public AuthenticatorWrapper() {
        authenticator = Play.application().injector().instanceOf(Security.Authenticator.class);
    }

    @Override
    public String getUsername(Http.Context ctx) {
        return authenticator.getUsername(ctx);
    }

    @Override
    public Result onUnauthorized(Http.Context ctx) {
        return authenticator.onUnauthorized(ctx);
    }
}

我只是使用 Play.application().injector() 访问器来获取 Guice 提供的 Security.Authenticator 实例。所以在我的 application.conf 中,我只是配置了一个 Guice 模块,它将 Security.Authenticator 绑定到想要的实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多