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.
Mocking should only be used as a last resort, even in unit tests. A method is not a unit, and even a class is not a unit. A unit is any logical separation of code that makes sense, regardless of what you call it.
Writing a Unit Test for REST Controller First, we need to create Abstract class file used to create web application context by using MockMvc and define the mapToJson() and mapFromJson() methods to convert the Java object into JSON string and convert the JSON string into Java object.
If you've writing custom filters, routes, etc, you should unit test them, but not as part of your tests on a particular controller action. They should be tested in isolation.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With