Testing 如何在Grails2.0服务中对i18n注入messageSource的使用进行单元或集成测试
我在Grails2.0项目中的一个服务中使用了一个消息包,用于国际化文本。用例是一个通过邮件插件以异步方式发送的电子邮件主题,因此在控制器或TagLib中使用它是没有意义的(考虑到不在服务中访问文本或视图的常见参数)。这段代码在我运行的Grails应用程序中运行良好,但我不确定如何测试它 我在我的定义中尝试了一个Testing 如何在Grails2.0服务中对i18n注入messageSource的使用进行单元或集成测试,testing,grails,service,internationalization,grails-2.0,Testing,Grails,Service,Internationalization,Grails 2.0,我在Grails2.0项目中的一个服务中使用了一个消息包,用于国际化文本。用例是一个通过邮件插件以异步方式发送的电子邮件主题,因此在控制器或TagLib中使用它是没有意义的(考虑到不在服务中访问文本或视图的常见参数)。这段代码在我运行的Grails应用程序中运行良好,但我不确定如何测试它 我在我的定义中尝试了一个PluginAwareResourceBundleMessageSource,因为这是我正在运行的应用程序注入的内容,但它导致了空指针,因为它似乎需要围绕插件管理器进行一系列设置,因此我
PluginAwareResourceBundleMessageSource
,因为这是我正在运行的应用程序注入的内容,但它导致了空指针,因为它似乎需要围绕插件管理器进行一系列设置,因此我的测试环境无法提供(甚至集成)
然后我尝试了一个reloadableSourceBundleMessageSource
,因为它是纯Spring,但它似乎看不到我的.properties文件,并且失败了,在区域设置“en”的代码“my.email.subject”下找不到任何消息
我觉得我有点像虫洞,因为Grails文档中没有记录在服务中访问Grails i18n,所以如果有更好的方法,请告诉我
注意my.properties文件位于标准的grails app/i18n
位置
测试
@TestFor(EmailHelperService)
class EmailHelperServiceTests {
void testSubjectsDefaultLocale() {
defineBeans {
//messageSource(PluginAwareResourceBundleMessageSource); Leads to nullpointers
messageSource(ReloadableResourceBundleMessageSource);
}
String expected = "My Expected subject Passed1 Passed2";
String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2);
assertEquals("email subject", expected, actual);
}
服务:
class EmailHelperService {
def messageSource;
public String getEmailSubject(Locale locale, String param1, String param2) {
Object[] params = [param1, param2].toArray();
return messageSource.getMessage("my.email.subject", params, locale );
}
在单元测试中,您可以通过执行以下操作来确保连接正确:
void testSubjectsDefaultLocale() {
def messageSource = new Object()
messageSource.metaClass.getMessage = {subject, params, locale ->
assert "my.email.subject" == subject
assert ["Passed1", "Passed2"] == params
assert Locale.ENGLISH == locale
"It Worked!!!"
}
service.messageSource = messageSource
String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2)
assert "It Worked!!!" == actual
}
这将有助于确保您正确连接,但无法确保您所做的实际工作正常。如果你对此感到满意,那么这将对你有用。如果您试图在为.properties文件指定“XYZ”时进行测试,它将返回“Hello”,那么这将不适用于您。Grails中的单元测试中已经有一个messageSource,它是一个StaticMessageSource(请参阅),您可以使用addMessage方法添加模拟消息:
messageSource.addMessage("foo.bar", request.locale, "My Message")
在单元测试和功能测试的本地端中,有时您需要18n目录中的真实属性 这对我很有用:
MessageSource getI18n() {
// assuming the test cwd is the project dir (where application.properties is)
URL url = new File('grails-app/i18n').toURI().toURL()
def messageSource = new ResourceBundleMessageSource()
messageSource.bundleClassLoader = new URLClassLoader(url)
messageSource.basename = 'messages'
messageSource
}
i18n.getMessage(key, params, locale)
您的目的是确保您正确地连接了这一测试吗?或者你打算为你所支持的每种语言写一本?您上面的测试也是单元测试还是集成测试?其目的不是检查spring连接,而是在各种语言得到支持时测试它们,并检查.properties和文本中键的正确性。为了可读性,我简化了参数,但需要测试它们的正确性。谢谢你的想法。我不太关心spring的连接,但我希望加载实际的grails.properties文件(直接加载或通过spring加载),而不是在测试中声明它,因为测试内容和密钥的正确性是我想要的。谢谢,很高兴知道-是否可以使用StaticMessageSource和带有{0}样式的占位符?为了回答我自己的评论,使用占位符进行了测试,效果很好。谢谢。我知道这个问题很老,但我发现它很有用,可以帮助我找到正确的方向。下面是我模拟消息源进行测试的解决方案。首先,我得到了消息源:
messageSource messageSource=getMessageSource()
messageSource确实在单元测试中,但它是空的。所以我按照@Graem Rocher的建议做了,并为messageSource填充了此测试的相关消息。messageSource.addMessage(“messageService.sms.aNumber.recovery.message”,Locale.default,“{0},您的A号是{1}”)
任何想知道它是否仍然适用的人。我已经用Grails 3.2.5对它进行了测试,它工作得很好。只需按@Graeme在回答中的建议调用messageSource.addMessage
。