Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play Framework 2.2.2 - Java -Testing Controllers With Mock Objects

Is anyone aware of any examples of testing a Java based Play Framework controller by setting mock objects? I am using Spring in my Play project so all my controller methods are not static.

Testing the tradional way, Play shows my controller as having static methods and I just cant see a way of how I can inject mocks into my object

Result result = callAction(
            controllers.routes.ref.LoginController.authenticate(),
        fakeRequest().withFormUrlEncodedBody(TestUtils.SUCCESSFUL_LOGIN_MAP)
    ); 

I have a number of services that need to be called in the LoginController and I would like to set those up as mocks

Any help is greatly appreciated

Thanks Damien

like image 239
Damien Avatar asked Jul 02 '26 19:07

Damien


1 Answers

I was looking for the solution of the same problem. So far the best result I was able to achieve is this:

public class MyObjectControllerTest{

    private final MyObjectDAO dao = mock(MyObjectDAO.class);
    private final MyObjectController controller = new MyObjectController(dao);

    public static FakeApplication fakeApplication;

    @BeforeClass
    public static void startApp() {
        fakeApplication = Helpers.fakeApplication();
        Helpers.start(fakeApplication);
    }

    @AfterClass
    public static void stopApp() {
        Helpers.stop(fakeApplication);
    }

    @Test(expected = NotFoundException.class)
    public void testFailWithUnknownMyObjectKey() throws Throwable {
        when(dao.getByKey(any(UUID.class), any(UUID.class), any(Boolean.class))).thenReturn(null);
        controller.get(CassandraUUIDs.timeBased());
    }

    @Test
    public void testGetSuccess(){
        MyObject deletedObject = MyObjectTestGenerator.generateMyObject();
        deletedObject.setDeleted(true);
        when(dao.getByKey(any(UUID.class), any(UUID.class), any(Boolean.class))).thenReturn(deletedObject);

        try {
            Result result = controller.get(CassandraUUIDs.timeBased());
            assertThat(status(result)).isEqualTo(Http.Status.GONE);
            assertThat(contentType(result)).isEqualTo(Http.MimeTypes.JSON);
            assertThat(contentAsString(result)).isEqualTo(ErrorMsg.OBJECT_DELETED.toJson().toString());
        } catch (MyObjectsException e) {
            e.printStackTrace();
            fail("Failed to send MyObject.get request.");
        }
    }
}

What I do here is instantiate an instance of the controller class and pass mocked DAO instance. Please note that I don't use static controller methods in my code as well.

One issue with this workaround I found so far is that Action (I have custom one) is not working. But Action can (and probably must) be tested separately.

like image 160
Vladimir Prudnikov Avatar answered Jul 04 '26 10:07

Vladimir Prudnikov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!