In application code when dealing with forms it is recommended to use a FormFactory to create a Form wrapper around the form of type T. But when it comes to testing, what is the way to create a Form? (Do you have to inject FormFactory in the test?)
My app does something similar to that:
class MyAmazingClass {
private final FormFactory formFactory;
@Inject
MyAmazingClass(FormFactory formFactory) {
this.formFactory = formFactory;
}
public CompletionStage<Result> myAmazingMethodHandlingForms() {
Form<String> form = formFactory.form(String.class).bindFromRequest();
// ... Actually doing something
return null;
}
}
What shall my test class (for unit testing) looks like?
I am trying something like this but I think I should not try to inject the FormFactory (also it does not seems to work):
public class MyAmazingClassTest extends WithApplication {
@Mock
FormFactory mockedFormFactory;
@Inject
FormFactory realFormFactory;
MyAmazingClass myAmazingClass;
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder().build();
}
@Before
public void setUp() throws Exception {
myAmazingClass = new MyAmazingClass(mockedFormFactory);
}
@Test
public void testMyAmazingMethodHandlingForms() throws Exception {
String myString = "ciao";
Form<String> stringForm = realFormFactory.form(String.class).fill(myString);
when(mockedFormFactory.form(eq(String.class)).bindFromRequest()).thenReturn(stringForm);
myAmazingClass.myAmazingMethodHandlingForms();
// Some assertions...
}
}
I am using JUnit 4, Java 8 and Play framework 2.5.
I would say that mixing mocks with the real application is not the best idea here. You should either use mocks (and avoid
WithApplication
), or you can use the "real" instances by callingapp.injector().instanceOf()
(including for yourMyAmazingClass
). For example, when only using mocks:Testing using the real instances would requires you to do a request, since apparently, you are binding from the request: