单元测试和Mac OS X 10.10.3语言和区域设置

时间:2015-09-26 11:51:25

标签: java macos maven locale

案例

在没有详细说明的情况下,mvn test在使用法语设置的系统上失败。为了通过回归测试来解决该问题,我想创建一个回归测试,它将语言环境设置为法语,并使用Maven运行单元测试。

我在System Preferences > Language & Region > Advanced > Format language中切换英语和法语。

问题

  1. 在英语区域设置中,我使用locale
  2. 检查设置
    LANG="en_GB.UTF-8"
    LC_COLLATE="en_GB.UTF-8"
    LC_CTYPE="en_GB.UTF-8"
    LC_MESSAGES="en_GB.UTF-8"
    LC_MONETARY="en_GB.UTF-8"
    LC_NUMERIC="en_GB.UTF-8"
    LC_TIME="en_GB.UTF-8"
    LC_ALL=
    
    1. 运行mvn test,它会通过

    2. 使用OS X GUI切换到法语区域设置

    3. 运行mvn test,它失败(正如预期的那样)

    4. 在同一个终端中运行locale - 它仍然会产生与以前相同的结果(虽然它不应该,因为我切换到法语)

    5. 打开新终端并运行locale

    6. LANG=
      LC_COLLATE="C"
      LC_CTYPE="UTF-8"
      LC_MESSAGES="C"
      LC_MONETARY="C"
      LC_NUMERIC="C"
      LC_TIME="C"
      LC_ALL=
      

      结果

      由于某种原因,locale命令的输出对应于终端启动时的区域设置。如果打开终端,通过GUI更改语言环境,然后运行locale命令,该命令对此命令不可见。

      随后,如果我通过导出LC_ALL或其他类型的变量来修改语言环境,这实际上并不会改变单元测试结果。如果我通过GUI更改语言环境,它将会。

      问题

      如何使用命令行更改语言环境,以便实际应用它们?

1 个答案:

答案 0 :(得分:1)

您可以通过多种方式设置DecimalFormat使用的语言环境。

您可以通过在pom中为surefire指定一些配置来设置Locale.getDefault返回的Locale(在DecimalFormat中使用)。例如,这将允许您拥有多个配置文件,每个配置文件都测试不同的区域设置。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>-Duser.language=fr -Duser.region=FR</argLine>
    </configuration>
</plugin>

或者您可以设置Locale.getDefault将在测试中返回的内容。在下面的示例中,有一个@ Before / @ After将Locale.getDefault恢复到之前的状态,以便更改defaultLocale不会影响其他测试

public class LocaleTest {

    private Locale localeBefore;

    @Before
    public void setUp() {
        localeBefore = Locale.getDefault();
    }

    @After
    public void revertLocale() {
        Locale.setDefault(localeBefore);
    }

    @Test
    public void passesInFRFRLocale() {
        Locale.setDefault(Locale.FRANCE);
        assertThat(DecimalFormat.getInstance().format(1000.01D), is(equalTo("1 000,01")));
    }

    @Test
    public void passesInENGBLocale() {
        Locale.setDefault(Locale.UK);
        assertThat(DecimalFormat.getInstance().format(1000.01D), is(equalTo("1,000.01")));
    }
}