Play Framework 1.x 使用@AllowFeature 控制器方法进行功能测试

Play Framework 1.x Functional Test with @AllowFeature Controller Method

我确实想为我们的项目编写一些功能测试。 Techstack:Play Framework 1.5,Java 16,Junit 3.

我找到了以下文档: test - 1.5.x security - 1.5.x

所以控制器看起来像这样。

@AllowFeature(Feature.SEARCH_BOX)
public static void search(String term) {
    //implementation omitted

    TablePage<MyAwesomeType> page = search(term);

    render(..., page, term);
}

我的测试是这样的

public class SearchTest extends FunctionalTest {

    @Test
    public void search_withResults() {
        String term = "ABC";
        Http.Response response = GET("/foo/search?term=" + term);

        assertStatus(302, response);

        assertThat(renderArgs("page"), is(notNullValue()));
        TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");

        assertTrue(page.getTotalRecords() >= 1);
    }

}

但是,TablePage<MyAwesomeType> page 为 null,但实际上不应该为 null,而且我无法使用调试器进入控制器方法。所以看起来控制器方法 search(...) 根本没有被调用。

响应代码是 302 - Found 但我认为这可能是播放建议它找到了路径 /foo/search

我的猜测是我需要设置一些 UserContext 或随请求一起发送 authenticityToken。所以play可以勾选需要的feature@AllowFeature(Feature.A_SEARCH_BOX).

有人知道我将如何设置这样的功能测试吗?

感谢任何帮助。谢谢!

我想通了。

我需要登录应用程序,然后 play FunctionalTest.class 会处理 cookie。

  1. 登录方式添加@NoAuthenticity
@NoAuthenticity // <-- This enables execution without authenticityToken
public static void login(@Required String username, @Required String password) {
    ... 
}
  1. Post测试前请求登录。
@Test
public void search_withResults() {
    // 1. login
    Map<String, String> credentials = Map.of("username", "MyUsername", "password", "MyPassword");
    POST("/login", credentials); 
    // Note: session info / authenticityToken is stored in a cookie
    // FunctionalTest.class makes sure to use this cookie for subsequent requests

    // This request now works like a charm
    String term = "ABC";
    Http.Response response = GET("/foo/search?term=" + term);

    assertStatus(302, response);

    assertThat(renderArgs("page"), is(notNullValue()));
    TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");

    assertTrue(page.getTotalRecords() >= 1);
}

注意:可以使用 JUnit @Before Annotation 来简化测试 class.

@Before
public void login(){
    Map<String, String> credentials = Map.of("username", "MyUsername", "password", "MyPassword");
    POST("/login", credentials);
}

@Test
public void search_withResults() {
    String term = "ABC";
    Http.Response response = GET("/foo/search?term=" + term);

    assertStatus(302, response);

    assertThat(renderArgs("page"), is(notNullValue()));
    TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");

    assertTrue(page.getTotalRecords() >= 1);
}

@Test
public void anotherTest() { ... }

@Test
public void yetAnotherTest() { ... }