使用Robolectric测试Android DecimalFormat

3
Android库对DecimalFormat类进行了修改,增加了一些好用的功能。当然,我需要其中的一个功能(有效数字符号:@)。

使用Robolectric进行测试时,似乎会使用标准的Java DecimalFormat类,这导致我的测试失败。

有没有办法告诉Robolectric使用Android版本?或者我应该在我的项目中包含DecimalFormat(从AOSP复制/粘贴类)?

以下是一个简化的示例:

如果我在以下设备上运行应用:

import java.text.DecimalFormat;
import java.util.Locale;

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        DecimalFormat decimalFormat = (DecimalFormat)java.text.NumberFormat.getInstance(Locale.US);
        decimalFormat.applyPattern("@@@");
        Log.d('SO', decimalFormat.format(0.0567467));
    }
}

它显示:

W/App:0.0567

在单元测试中:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import java.text.DecimalFormat;
import java.util.Locale;

import static junit.framework.TestCase.assertEquals;


@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class NumberFormatTest {
    @Test
    public void testSignificantDigit() {
        DecimalFormat decimalFormat = (DecimalFormat)java.text.NumberFormat.getInstance(Locale.US);
        decimalFormat.applyPattern("@@@");
        assertEquals("0.0567", decimalFormat.format(0.0567467));
    }
}

运行测试将输出:

junit.framework.ComparisonFailure:

期望值:0.0567

实际值:@@@0


定义:使我的测试失败加入一些不错的附加功能...添加一些代码... - Selvin
1
请提供一个最小的测试,以展示问题。这将成为有用答案的种子。在测试类上包含任何Robolectric属性。 - weston
由于format()返回一个StringBuffer,你尝试过在它上面调用toString吗? - Shine
@Selvin 加上一些不错的补充,实际的Android添加链接在原问题中。但你说得对,我已经添加了一个简单的测试用例来说明这个问题。 - fstephany
@ShineпјҢиҜҘж–№жі•зҡ„зӯҫеҗҚжҳҜ final String format(double value)гҖӮиҝҳжңүе…¶д»–иҝ”еӣһStringBuilderзҡ„ж јејҸеҢ–ж–№жі•пјҢдҪҶе®ғ们дёҚжҳҜжҲ‘дҪҝз”Ёзҡ„йӮЈдәӣгҖӮе°Ҫз®ЎеҰӮжӯӨпјҢжҲ‘д»Қ然е°қиҜ•дәҶtoString()пјҢдҪҶжөӢиҜ•з»“жһңеӨұиҙҘзӣёеҗҢгҖӮ - fstephany
1
请参考并提问 https://github.com/robolectric/robolectric/issues/2071 - Eugen Martynov
1个回答

0

正如官方Android文档所述,当在Android运行时(ART)中运行Java代码时,所提供的实现与常规JVM中的实现不同。

RoboElectric不在常规Android手机或模拟器上运行测试,而是在JVM上运行。这个JVM在您的主机系统上运行,没有这个修改后的DecimalFormat运行时实现版本。因此,据我所知,当在JVM中运行测试代码时,Android提供的功能不可用。要使用它,请在Android手机上运行测试,但是对于那个测试,您可能会放弃RoboElectric,而使用提供的测试工具

另一个合理的问题:为什么要测试Android类?我猜Google已经为其更改编写了测试,并跟踪了这一点,因此您不应该测试系统向您提供的功能


1
这正是问题所在: 有没有办法告诉Robolectric使用Android版本?或者我应该在我的项目中包含DecimalFormat(从AOSP复制/粘贴类)?提供的示例很简单,只是为了展示失败的行为。我的应用程序具有复杂的数字格式化方案。我希望能确保在正确的情况下选择正确的方案。我还有另一组在Espresso上运行的测试,但我的直觉告诉我,数字格式化属于单元测试。 - fstephany
如果您想确保选择了正确的格式,请进行测试!然后,您的测试应确保“selectCorrectFormat”函数选择/返回了正确的格式字符串。无需测试格式本身,因为这是Android系统的一部分。 - Capricorn
你可能不需要使用像 Espresso 这样的第三方库,而可以使用 Android 仪器化单元测试。详情请参见:https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html - Capricorn
是的,这就是我的最终结果:测试模式生成。但这样会导致难以阅读、丑陋的单元测试。对于瞥一眼测试(因为应用程序在计算方面很重要)的科学家来说,它们没有任何意义。这就像测试正则表达式一样,我喜欢添加一些示例/边界情况作为说明。 - fstephany

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接