如何创建表单<;T>;对于play(java)单元测试,现在Form.Form()已被弃用?

如何创建表单<;T>;对于play(java)单元测试,现在Form.Form()已被弃用?,java,unit-testing,playframework,junit4,playframework-2.5,Java,Unit Testing,Playframework,Junit4,Playframework 2.5,在处理表单的应用程序代码中,建议使用FormFactory围绕T类型的表单创建表单包装器。但在测试中,创建表单的方法是什么?(测试中是否必须注入FormFactory?) 我的应用程序执行类似的操作: class MyAmazingClass { private final FormFactory formFactory; @Inject MyAmazingClass(FormFactory formFactory) { this.formFactory

在处理表单的应用程序代码中,建议使用FormFactory围绕T类型的表单创建表单包装器。但在测试中,创建表单的方法是什么?(测试中是否必须注入FormFactory?)

我的应用程序执行类似的操作:

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;
    }
}
class MyAmazingClass{
私人最终模板厂;
@注入
MyAmazingClass(FormFactory FormFactory){
this.formFactory=formFactory;
}
公共完成阶段myAmazingMethodHandlingForms(){
Form Form=formFactory.Form(String.class).bindFromRequest();
//…真的在做什么
返回null;
}
}
我的测试类(用于单元测试)应该是什么样子

我正在尝试类似的方法,但我认为我不应该尝试注入FormFactory(而且它似乎不起作用):

公共类MyAmazingClassTest随应用程序扩展{
@嘲弄
FormFactory模拟FormFactory;
@注入
FormFactory realFormFactory;
MyAmazingClass MyAmazingClass;
@凌驾
受保护的应用程序ProviderApplication(){
返回新的GuiceApplicationBuilder().build();
}
@以前
public void setUp()引发异常{
myAmazingClass=新的myAmazingClass(mockedFormFactory);
}
@试验
public void testMyAmazingMethodHandlingForms()引发异常{
字符串myString=“ciao”;
formstringform=realFormFactory.Form(String.class).fill(myString);
当(mockedFormFactory.form(eq(String.class)).bindFromRequest()时。然后返回(stringForm);
myAmazingClass.myAmazingMethodHandlingForms();
//一些断言。。。
}
}

我正在使用JUnit 4、Java 8和Play framework 2.5。

我想说,将模拟与实际应用程序混合在一起并不是最好的主意。您应该使用mock(并避免使用应用程序
),或者可以通过调用
app.injector().instanceOf()
(包括您的
MyAmazingClass
)来使用“真实”实例。例如,仅使用模拟时:

public class MyAmazingClassTest {

    @Test
    public void testMyAmazingMethodHandlingForms() throws Exception {
        Form<String> form = mock(Form.class);
        // setup the mocked form as you expect it to behave

        FormFactory formFactory = mock(FormFactory.class);
        when(formFactory.form(eq(String.class)).bindFromRequest()).thenReturn(form);

        MyAmazingClass myAmazingClass = new MyAmazingClass(formFactory);
        myAmazingClass.myAmazingMethodHandlingForms();

        // Some assertions...
    }
}
公共类MyAmazingClassTest{
@试验
public void testMyAmazingMethodHandlingForms()引发异常{
Form=mock(Form.class);
//按照预期的方式设置模拟表单
FormFactory-FormFactory=mock(FormFactory.class);
when(formFactory.form(eq(String.class)).bindFromRequest())。然后返回(form);
MyAmazingClass MyAmazingClass=新的MyAmazingClass(formFactory);
myAmazingClass.myAmazingMethodHandlingForms();
//一些断言。。。
}
}
使用真实实例进行测试需要您执行一个请求,因为显然,您是从请求绑定的:

public class MyAmazingClassTest extends WithApplication {

    @Test
    public void testMyAmazingMethodHandlingForms() throws Exception {
        Map<String, String> formData = new HashMap<>();
        formData.put("some", "value");
        // fill the form with the test data
        Http.RequestBuilder fakeRequest = Helpers.fakeRequest().bodyForm(formData).method(Helpers.POST);

        Result result = Helpers.route(app, fakeRequest);

        // make assertions over the result or something else.
    }
}
公共类MyAmazingClassTest随应用程序扩展{
@试验
public void testMyAmazingMethodHandlingForms()引发异常{
Map formData=new HashMap();
formData.put(“一些”、“值”);
//用测试数据填写表格
Http.RequestBuilder fakeRequest=Helpers.fakeRequest().bodyForm(formData).method(Helpers.POST);
结果=Helpers.route(app,fakeRequest);
//对结果或其他事情做出断言。
}
}

感谢您的回答,我喜欢您介绍加载“真实”实例的可能性(因为我稍后还想进行集成测试),这将非常有用。但是,你为什么告诉我不应该扩展WithApplication?如果应用程序没有启动,我应该如何运行测试?(java.lang.RuntimeException:没有启动的应用程序)我认为扩展应用程序并提供GuiceApplicationBuilder.build()或Helpers.fakeapplication()是实现这一点的方法。然后您可以接受答案。因此,此问题不会出现在“未回答”筛选器中。抱歉,我仍在编辑评论(而您的回复速度太快!),因为我不知道enter键会为我添加评论。请再看一下。如果您使用的是mock,则不需要运行的应用程序。整个想法是单独测试组件。因此,如果
MyAmazingClass
需要访问该应用程序,您也需要模拟它。第二个例子扩展了应用程序,因为现在我们使用的是真正的组件。看起来它只需要“FormFactory”,所以这就足够了。
public class MyAmazingClassTest extends WithApplication {

    @Test
    public void testMyAmazingMethodHandlingForms() throws Exception {
        Map<String, String> formData = new HashMap<>();
        formData.put("some", "value");
        // fill the form with the test data
        Http.RequestBuilder fakeRequest = Helpers.fakeRequest().bodyForm(formData).method(Helpers.POST);

        Result result = Helpers.route(app, fakeRequest);

        // make assertions over the result or something else.
    }
}