Jam*_*ory 8 java testing unit-testing playframework
先决条件:我正在使用Play的最新版本!框架和Java版本(不是Scala).
我需要在创建用户时将消息发布到消息队列,并且我想测试该行为.我的问题是让这个很容易测试.
在其他框架中,我将要做的是在控制器中使用构造函数注入并在我的测试中传入一个模拟队列; 然而,玩Play!控制器是静态的,这意味着我new MyController(mockedQueue)
在测试中无法做到.
我可以使用Google Guice并@Inject
在我的控制器中的静态字段上添加注释,但这对我来说并不是很好,因为它或者意味着我必须将该字段公开以在测试中被替换,或者我必须在我的测试中使用容器.我更喜欢使用构造函数注入,但玩!似乎不方便.
通常说你的逻辑应该在你的模型中,而不是你的控制器.那讲得通; 但是,我们在这里不是Ruby,让你的实体与外部服务(电子邮件,消息队列等等)进行交互的可测试性远远低于动态环境,在这种环境中你可以MessageQueue
随意用模拟实例替换静态调用.
如果我让我的实体调用队列,那怎么可测试?
当然,如果我进行端到端的集成测试,这两种情况都是不必要的,但我不需要为我的测试运行而调整消息队列或SMTP服务器.
所以我的问题是:我如何模拟我的游戏!控制器和/或模型,以促进测试与外部服务的交互?
据我所知,对此没有一个干净的解决方案。
您可以将抽象工厂用于您的依赖项。该工厂可以为其生成的对象提供 setter 方法。
public class MyController {
...
private static ServiceFactory serviceFactory = ServiceFactory.getInstance();
...
public static void action() {
...
QueueService queue = serviceFactory.getQueueService();
...
}
Run Code Online (Sandbox Code Playgroud)
}
您的测试将如下所示:
public void testAction() {
QueueService mock = ...
...
ServiceFactory serviceFactory = ServiceFactory.getInstance();
serviceFactory.setQueueService(mock);
...
MyController.action();
verify(mock);
}
Run Code Online (Sandbox Code Playgroud)
如果您不想公开工厂的 setter 方法,您可以创建一个接口并在测试中配置实现类。
另一种选择是使用PowerMock来模拟静态方法。我以前用过,在大多数情况下效果都很好。只是不要过度使用它,否则你将陷入维护地狱......
最后,由于您愿意在应用程序中使用 Guice,这可能是一个可行的选择。
祝你好运!
归档时间: |
|
查看次数: |
1906 次 |
最近记录: |