How to unit or integration test use of injected messageSource for i18n in Grails 2.0 service

北城余情 提交于 2019-12-18 03:17:10

问题


I make use of a message bundle in one of my services in a Grails 2.0 project for internationalized text. The use case is an email subject that is sent via the mail plugin in an asynchronous way, so it really doesn't make sense to have this in a controller or TagLib (given the usual argument of not accessing your text or views in a service). This code works fine in my running Grails app, but I'm not sure how to test it.

I tried a PluginAwareResourceBundleMessageSource in my defineBeans as that is what my running application injects, but it led to nullpointers as it appears it needs a bunch of setup around plugin managers and such that my test environment is not giving (even integration).

I then tried a ReloadableResourceBundleMessageSource as it was pure Spring, but it can't seem to see my .properties files, and fails with a No message found under code 'my.email.subject' for locale 'en'.

I feel like I'm going down a wormhole a bit as accessing Grails i18n in a service is not documented in the grails docs, so if there is a preferred way to do this, let me know.

Note my .properties file is in the standard grails-app/i18n location.

The test

@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);

}

Service:

    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 );      
    }

回答1:


There is already a messageSource in unit tests in Grails, it is a StaticMessageSource (see http://static.springsource.org/spring/docs/2.5.4/api/org/springframework/context/support/StaticMessageSource.html), you can add mock messages with the addMessage method:

messageSource.addMessage("foo.bar", request.locale, "My Message")



回答2:


In unit tests and the local side of functional tests, sometimes you want the real properties that are in the 18n directory.

This works for me:

  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)



回答3:


In a unit test you could ensure that you're wired up correctly by doing something like this:

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
}

This will help ensure that you're wired up correctly but it will not ensure that what you're doing actually works. If you're comfortable with that then this would work for you. If you're trying to test that when you give "XYZ" to your .properties file it returns "Hello" then this will not work for you.



来源:https://stackoverflow.com/questions/9134520/how-to-unit-or-integration-test-use-of-injected-messagesource-for-i18n-in-grails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!