既然 Form.form() 已弃用,如何为播放 (java) 单元测试创​​建 Form<T>?

How to create a Form<T> for a play (java) unit test now that Form.form() is deprecated?

在处理表单的应用程序代码中,建议使用FormFactory 为类型T 的表单创建一个Form 包装器。但是当涉及到测试时,创建Form 的方法是什么? (测试时一定要注入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(用于单元测试)应该是什么样的?

我正在尝试这样的事情,但我认为我不应该尝试注入 FormFactory(它似乎也不起作用):

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...
    }
}

我正在使用 JUnit 4、Java8 和 Play 框架 2.5。

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

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...
    }
}

使用真实实例进行测试需要您发出请求,因为很明显,您是从请求中绑定的:

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.
    }
}