Reputation: 8240
The title pretty much says it all. I would like to set up a traditional JUnit test to mock a controller's dependencies and run tests against actions.
I've found that I can achieve my goal like this:
public class AccountsControllerTest {
private controllers.Accounts accountsController;
@Test
public void test() {
running(fakeApplication(), new Runnable() {
public void run() {
accountsController = new controllers.Accounts();
accountsController.setAccountsWorkflow(mock(workflow.Accounts.class));
}
});
}
}
The obvious problem here is that I'm instantiating my class under test and injecting mock dependencies from the test method itself, when I should be doing that in the setup()
method. It seems that the setup()
method is useless if I'm going to test my controller in a traditional way.
Of course I can test controllers the way Play recommends, but my application is dependent on an external SOAP web service, so I need unit tests to show that our code is working when their servers are down.
So, what's the best way to unit test a Play controller using mocks while still taking advantage of setup()
and teardown()
methods?
Edit
I realize I'm assuming some knowledge here, so for those who are unaware, controller instantiation in a unit test must be wrapped in a running()
function or Play! will throw a runtime exception saying that no application has been started.
Upvotes: 8
Views: 7281
Reputation: 462
You could accomplish this using Mockito and Play's FakeApplication and setting the static Http.Context variable.
This way you can write the test like all other JUnit test.
Example:
...
import static play.test.Helpers.status;
import play.test.FakeApplication;
import play.test.Helpers;
import play.mvc.Http;
import play.mvc.Result;
...
@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {
public static FakeApplication app;
@Mock
private Http.Request request;
@BeforeClass
public static void startApp() {
app = Helpers.fakeApplication();
Helpers.start(app);
}
@Before
public void setUp() throws Exception {
Map<String, String> flashData = Collections.emptyMap();
Http.Context context = new Http.Context(request, flashData, flashData);
Http.Context.current.set(context);
}
@Test
public void testIndex() {
final Result result = Application.index();
assertEquals(play.mvc.Http.Status.OK, status(result));
}
@AfterClass
public static void stopApp() {
Helpers.stop(app);
}
Upvotes: 1