在 Java Play 2.4 中测试具有模拟依赖项的控制器

Posted

技术标签:

【中文标题】在 Java Play 2.4 中测试具有模拟依赖项的控制器【英文标题】:Testing a controller with mocked dependencies in Java Play 2.4 【发布时间】:2015-07-17 05:15:32 【问题描述】:

我正在从 2.37 -> 2.4.1 迁移我的 Java Play 应用程序。在我的控制器单元测试中,我在每次测试之前都设置了控制器及其相关的模拟依赖项。

似乎 getControllerInstance 方法已从 Play 2.4 中的 GlobalSettings 中删除,所以现在我无法覆盖它来返回我的控制器实例。

@RunWith(MockitoJUnitRunner.class)
public class PublicRoomsControllerTest extends WithApplication 

    @Mock
    private MyService myService;

    private MyController myController;

    @Before
    public void setUp() 
        myController = new MyController(myService);

        GlobalSettings global = new GlobalSettings() 

            public <T> T getControllerInstance(Class<T> clazz) 
                return (T) controller;
            

        ;

        start(fakeApplication(global));
    

    @Test
    public void myTest() 
        Result result = route(new RequestBuilder().method(POST).uri("/test"));
        assertEquals(OK, result.status());
    


我知道我可以从我的测试中直接在我的控制器实例上调用该方法,例如:

Result result = myController.someMethod();
assertEquals(OK, result.status());

这种方法似乎可以正常工作,直到 someMethod() 依赖于请求中的表单数据,例如

 Map<String, String> data = Form.form().bindFromRequest().data();

测试是否可以通过某种方式路由请求(可能包括表单数据)以使用我的控制器实例?

(我正在使用 Guice、Mockito 和 JUnit)

【问题讨论】:

【参考方案1】:

正如https://github.com/playframework/playframework/issues/4876 向我指出的那样。在 Play 2.4.x 中执行此操作的正确方法是使用 Helpers.invokeWithContext。因此,为了使用我的模拟依赖项测试我的控制器,我使用了以下代码:

RequestBuilder requestBuilder = new RequestBuilder().bodyForm(ImmutableMap.of("userId", 1));
Result result = new Helpers().invokeWithContext(requestBuilder, () -> myController.someMethod());

旁注:我相信 invokeWithContext 将来会被更改为静态方法。

【讨论】:

以上是关于在 Java Play 2.4 中测试具有模拟依赖项的控制器的主要内容,如果未能解决你的问题,请参考以下文章

Java Play 2.4 使用注入为类编写测试用例

在 Akka actor 中玩 2.4 依赖注入

Play 2.4 WebSocket在使用编译时依赖注入时抛出InstantiationException

在 Play 2.4 scala 中禁用单个测试

玩 2.4:如何使用 MultipartFormData 编写文件上传测试用例

如何使用Slick和Play在测试中应用手动演变! 2.4