Grails Locale not set for Spock unit tests

依然范特西╮ 提交于 2020-01-02 18:36:20

问题


In my Grails 2.2 application I make some calculations which requires Locale to be set correctly. Therefore I provide this configuration block in my application, as mentioned elsewhere.

grails-app/config/spring/resources.groovy:

beans = {
    localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
        defaultLocale = new Locale("da","DK")
        java.util.Locale.setDefault(defaultLocale)
    }
}

Now, as also suggested by other questions and answers, this works in my context for the running application but not for unit tests.

I made this snippet to verify (on a page in the application):

<h2>Locale settings</h2>
<p>The following properties relevant to Locale is configured:</p>
<pre>
LocaleContextHolder.locale:              '${org.springframework.context.i18n.LocaleContextHolder.locale}'
java.util.Locale.getDefault():           '${java.util.Locale.getDefault()}'
RequestContextUtils.getLocale(request):  '${org.springframework.web.servlet.support.RequestContextUtils.getLocale(request)}'
session['SessionLocaleResolver.LOCALE']: '${session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE']}'
</pre>

which renders

Locale settings

The following properties relevant to Locale is configured:

LocaleContextHolder.locale:              'da_DK'
java.util.Locale.getDefault():           'da_DK'
RequestContextUtils.getLocale(request):  'da_DK'
session['SessionLocaleResolver.LOCALE']: '' 

But for unit testing it does not work

The problem occurs for my unit test (I need java.util.Calendar weeks to start on Mondays (default for da_DK, but the week starts on Sunday (default for en_* locales).

In this case I made two test cases:

In test/unit/DefaultLocaleSpec.groovy:

import grails.test.mixin.TestMixin
import grails.test.mixin.web.ControllerUnitTestMixin
import org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest
import org.springframework.web.servlet.support.RequestContextUtils
import spock.lang.Specification

@TestMixin(ControllerUnitTestMixin)
class DefaultLocaleSpec extends Specification {

    // ---------------------------------
    //       Locale verification (affects java Calendar calculations)
    // ---------------------------------
    def "locale (request) should be set to Danish, so that week starts Monday"() {
        given:
        GrailsMockHttpServletRequest request = new GrailsMockHttpServletRequest()
        when:
        Locale result = RequestContextUtils.getLocale(request)
        then:
        result == new Locale("da", "DK")
    }

    def "locale (default) should be set to Danish, so that week starts Monday"() {
        when:
        Locale result = java.util.Locale.getDefault()

        then:
        result == new Locale("da", "DK")
    }

The two tests fail with the following messages:

Condition not satisfied:

result == new Locale("da", "DK")
|      |  |
en     |  da_DK
       false

    at DefaultLocaleSpec.locale (request) should be set to Danish, so that week starts Monday(DefaultLocaleSpec.groovy:27)


Condition not satisfied:

result == new Locale("da", "DK")
|      |  |
en_US  |  da_DK
       false
 <Click to see difference>

    at DefaultLocaleSpec.locale (default) should be set to Danish, so that week starts Monday(DefaultLocaleSpec.groovy:35)

One workaround I found was to add the following to the unit test file:

def setupSpec() {
    java.util.Locale.setDefault(new Locale("da", "DK"))
}

I feel tempted to pick that as a solution, but then I may have to add it to all my unit test file to fix the locale. And it seems like repeated work. I prefer my code more DRY (don't repeat yourself).

Option to change my machine's default Locale.

This I like to avoid, since everything I have to do to modify my setup, my colleagues also have to learn. Less customization is better. The more I can put inside the application, the better for me, my colleagues and any maintainers of the code :)

Question

This pinpoints my actual problem: I want to set up correct (default) locale also for the unit testing environment. How to do that – in a DRY way?

I prefer to make one change in one file which globally affects my app.

Related questions

These related questions do not quite answer or solve my problem (but have related ideas)

  • SO: How can I force Grails to use only one language? – suggests all problems are solved by setting locale in resources.groovy but does not address unit testing
  • SO: Retrieve active locale in Grails application – suggestions to read and change locale and default locale (does not address unit testing)

来源:https://stackoverflow.com/questions/30284984/grails-locale-not-set-for-spock-unit-tests

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