1

我有一台英语设置的笔记本电脑,我的同事有一台德语笔记本电脑。我有一个单元测试如下:

  @Test
  public void myTest() {
    String randomValue = roundFloat(4, 0.32258437873357226);
    Assert.assertEquals(Double.parseDouble(randomValue), 0.3225);
  }

  public String roundFloat(int decimalDigits, Number randomValue) {

    String formatPattern = getFormatPattern(decimalDigits);
    DecimalFormat decimalFormat = new DecimalFormat(formatPattern);
    decimalFormat.setRoundingMode(RoundingMode.FLOOR);
    return decimalFormat.format(randomValue);
  }

英文的默认小数分隔符是.,而德文的默认小数分隔符是,. 因此,该测试在我的机器上运行良好,但是当我的同事运行它时,它抱怨:

java.lang.NumberFormatException: For input string: "0,3225"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)
    at de.vwag.fda.common.MeteringUnitTest.roundFloatTest(MeteringUnitTest.java:174)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
    at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
    at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
    at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
    at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
    at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.testng.TestRunner.privateRun(TestRunner.java:794)
    at org.testng.TestRunner.run(TestRunner.java:596)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
    at org.testng.SuiteRunner.run(SuiteRunner.java:276)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
    at org.testng.TestNG.runSuites(TestNG.java:1063)
    at org.testng.TestNG.run(TestNG.java:1031)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:135)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:193)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:94)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:146)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:377)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:138)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:465)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:451)

那么,我该如何修改我的测试,以便它针对所有可能的本地设置运行?

4

2 回答 2

0

我只会使用System.printf正确的语言环境。

System.out.printf(Locale.GERMAN, "%.3f%n", 123.723);
System.out.printf(Locale.ENGLISH, "%.3f%n", 123.723);

印刷

123,723
123.723

但是格式化程序也接受语言环境。所以如果你想做货币,你可以打电话:

NumberFormat df = NumberFormat.getCurrencyInstance(Locale.ENGLISH);

您可以四舍五入到指定的位数,如下所示。

String randomValue = roundFloat(4, .32258437873357226, Locale.GERMAN);
System.out.println(randomValue);
randomValue = roundFloat(7,.32258437873357226, Locale.ENGLISH);
System.out.println(randomValue);

印刷

0,3225
0.3225843

roundFloat 方法

public static String roundFloat(int decimalDigits, Double randomValue, Locale locale) {
    DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(locale);
    df.setMaximumFractionDigits(decimalDigits);
    df.setRoundingMode(RoundingMode.FLOOR);
   return df.format(randomValue);
}
于 2021-06-21T13:40:58.827 回答
0

DecimalFormat 文档

To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance(). In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat.

这意味着您可以使用它来获取具有自定义语言环境的数字格式化程序,并像在代码中那样设置舍入模式:

NumberFormat format = NumberFormat.getNumberInstance(Locale.GERMAN);
if(format instanceof DecimalFormat) {
    ((DecimalFormat) format).setRoundingMode(RoundingMode.FLOOR);
}
于 2021-06-21T13:38:55.907 回答