Reputation: 171
I am trying to write some unit tests for my Play Framework 2.4.6 application. I need WS for my purposes testing. However, when I used the documention's method to inject WS I end up with a null pointer if used in a test or a model. However, the injection works perfectly if I install it into one of my controllers.
Here is my test:
import org.junit.Test;
import play.test.WithServer;
import play.libs.ws.*;
import javax.inject.Inject;
import static play.test.Helpers.running;
import static play.test.Helpers.testServer;
public class UserProfileTests extends WithServer {
@Inject
WSClient ws;
@Test
public void demographicTest() {
System.out.println(ws.toString()); //null pointer exception
running(testServer(3333), () -> {
System.out.println(ws.toString()); //null pointer exception
});
}
}
Here is the console output when running activator test
[error] Test UserProfileTests.demographicTest failed: java.lang.NullPointerException: null, took 5.291 sec
[error] at UserProfileTests.demographicTest(UserProfileTests.java:15)
[error] ...
[error] Failed: Total 4, Failed 1, Errors 0, Passed 3
[error] Failed tests:
[error] UserProfileTests
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 9 s, completed Jan 21, 2016 11:54:49 AM
I'm sure I'm just fundamentally misunderstanding something about dependency injection or how the system works. Any help would be very appreciated.
Upvotes: 3
Views: 1556
Reputation: 12214
Since tests should be extremely focused on just one particular scanario/object, I don't think you need to worry about how to do Dependency Injection for your tests and, instead, just instantiate what you need. Here is a way to instantiate using the application Injector
:
import org.junit.Before;
import org.junit.Test;
import play.libs.ws.WSClient;
import play.test.WithServer;
public class UserProfileTests extends WithServer {
private WSClient ws;
@Before
public void injectWs() {
ws = app.injector().instanceOf(WSClient.class);
}
@Test
public void demographicTest() {
System.out.println(ws);
}
}
But, of course, you could also just instantiate the ws
by hand or mock it if you want.
About the models
, their lifecycle is not handled by Guice and then, there is no direct way to do Dependency Injection at models. You can always find a way to do that, but should you? What will happen if try to load 100 objects from the database and then have to inject a dependency in each of these objects?
Besides the (likely) performance problem, maybe you are also violating Single Responsibility Principle here and your models are doing to much work.
Upvotes: 6