【问题标题】:call to Android API always returns 0 in a unit test在单元测试中调用 Android API 总是返回 0
【发布时间】:2017-08-13 12:20:06
【问题描述】:

我正在尝试计算两个位置之间的距离,我尝试了 location.distanceTo 和 Location.distanceBetween 方法,但在这两种情况下都返回 0,我不确定我做错了什么。这是我的方法:

public static double distance(double lat1, double lon1, double lat2, double lon2, DistanceUnit unit) {
    Location location1 = new Location("");
    location1.setLatitude(lat1);
    location1.setLongitude(lon1);
    Location location2 = new Location("");
    location2.setLatitude(lat2);
    location2.setLongitude(lon2);
    // Distance in km
    double dist = location1.distanceTo(location2) / 1000;

    if (unit == DistanceUnit.Miles) {
        // Distance in miles
        dist = dist / 1.6;
    }
    return dist;
}

我正在运行的单元测试,以确保测试运行是:

@Test
public void testDistance() {
    double lat1 = 40.2582279;
    double lon1 = -75.2654062;

    double lat2 = 40.476492;
    double lon2 = -75.355655;

    double distance = LocationUtils.distance(lat1, lon1, lat2, lon2, DistanceUnit.Kilometer);

    Assert.assertEquals(20, distance, 2);

}

我得到的结果是:

java.lang.AssertionError: 
Expected :20.0
Actual   :0.0

提前致谢

【问题讨论】:

    标签: android location distance


    【解决方案1】:

    您是否尝试在手机/模拟器上运行的应用中使用LocationUtils.distance() 方法?我猜它在这种情况下会像你期望的那样工作。

    当您运行单元测试时,它是在您的计算机上运行的,而不是在 Android 设备上运行的。您不能使用内置的 Android 类(如 Location)。来自the docs

    默认情况下,适用于 Gradle 的 Android 插件会针对不包含任何实际代码的 android.jar 库的修改版本执行本地单元测试。相反,单元测试中对 Android 类的方法调用会引发异常。这是为了确保您只测试您的代码,而不依赖于 Android 平台的任何特定行为(您没有明确模拟)。

    您似乎遇到了这个异常,应该是这样的

    java.lang.RuntimeException: Method setLatitude in android.location.Location not mocked. See http://g.co/androidstudio/not-mocked for details.
        at android.location.Location.setLatitude(Location.java)
        at example.com.stackoverflow.LocationUtils.distance(LocationUtils.java:13) 
    

    然后您是否阅读了this 告诉您可以添加

    android {
      ...
      testOptions {
        unitTests.returnDefaultValues = true
      }
    }
    

    到您的build.gradle 文件?这确实可以防止 android 类在您尝试使用它们时抛出异常,但请注意,这样做是为了

    改变行为,让方法返回 null 或零

    这正是您所看到的行为:location1.distanceTo(location2) 返回 0。


    更一般地说,这个特定的单元测试似乎没有必要;您主要是在测试 Android API,而不是测试您自己的逻辑。除非有部分您的代码,否则您要确保经过测试?你把正确的纬度/经度放在一起吗?单位转换按预期工作?也许您可以提取您担心的任何部分的逻辑并对其进行单元测试。

    【讨论】:

    • 这解释了它,我试图根据不同的条件对列表进行排序,距离就是其中之一,我试图对我的比较器进行单元测试。感谢您的详细回复。
    猜你喜欢
    • 2018-07-31
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多