先决条件:我使用的是最新版本的Play! framework和Java版本(不是Scala)。测试与外部服务的交互
我需要在创建用户时向消息队列发布消息,并且我想测试该行为。我的问题是使这个易于测试。
的控制方法
在其他框架,我就做了是使用构造器注入到控制器,并通过在我的测试中嘲笑队列;但是,与Play!控制器是静态的,这意味着我不能在我的测试中做new MyController(mockedQueue)
。
我可以使用Google Guice并将一个@Inject
注释放在控制器的静态字段中,但对我来说这并不好,因为这意味着我必须将该字段公开为在测试中被替换,或者我必须在测试中使用容器。我更喜欢使用构造函数注入,但玩!似乎并没有促进这一点。
模型方法
人们常常说你的逻辑应该是在你的模型,而不是你的控制器。这就说得通了;然而,我们不在Ruby这里,让你的实体与外部服务(电子邮件,消息队列等等)交互...比在动态环境中可测试性要差得多,在这种环境中,你可以用一个模拟实例替换你的静态调用将。
如果我让实体呼叫进入队列,那么可测试性如何?
当然,如果我进行端到端的集成测试,这两种情况都是不必要的,但我宁愿不需要消息队列或SMTP服务器启动我的测试运行。
所以我的问题是:我该如何建模我的Play!控制器和/或模型来促进测试与外部服务的交互?
“ServiceFactory”方法存在的一个*潜在问题是该字段将被初始化;因为它是一个静态字段,所以'getInstance'可能会在您有机会替换实例之前被初始化程序调用。只是大声思考,没有实际验证这一点。 –
实际上,在这个例子中,ServiceFactory是一个Singleton。您不会替换ServiceFactory本身,而是替换它生成的QueueService。 –
是的,我明白了;但是,由于该字段是静态的,因此在您能够替换从getInstance返回的任何值之前,它将被初始化。您通常无法控制执行静态初始化程序的时间,因此可能会在测试设置发生之前发生。 –