I have a play application with authenticated routes. I implemented an Authenticator, storing users into elasticsearch. My securized methods in my controllers are annotated with the @Security.Authenticated
annotation. For my unit tests with mockito, I would like to mock this class but I don't know how to do this.
I am using DI with Guice. So I tried this approach:
Develop an AuthenticatorWrapper as following:
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;
}
}
This class has an Authenticator as parameter, which is supposed to be injected by Guice when the app starts.
I developed a guice module defining a binding for class Authenticator.class
to MyCustomAuthenticator.class
My securized route are annotated with @Security.Authenticated(AuthenticatorWrapper.class)
In my test I can easily provide a mock of class MyCustomAuthenticator
my creating the mock, define test scope guice module, and defining a binding from Authenticator.class
to my mock.
I thought this should work but this is not the case. Both at normal runtime or from my tests, the binding seems not working. I have nullPointerException
from the wrapper when: the Authenticator
parameter is not injected by Guice.
So my questions are:
MyCustomAuthenticator
into the annotations, but how can I mock this authenticator in my tests?Thanks :)
A found a workaround. I just used an access method provided by Play framework 2.4 since it fully integrates Guice. Here is my Authentication Wrapper class:
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);
}
}
I just use the Play.application().injector() accessor to get a Security.Authenticator instance provided by Guice. So in my application.conf, I just configure a Guice Module which binds Security.Authenticator to the wanted implementation.