如何在类中测试serielize方法的正确方法?

时间:2015-09-16 14:38:32

标签: java android unit-testing

我在类中有这个方法,它在JSONObject中序列化了类的属性,非常简单:

public String serialize(){
    JSONObject wifiToAddJson = null;
    try {
        wifiToAddJson = new JSONObject();
        wifiToAddJson.put("wifi_ssid", wifi_ssid);
        wifiToAddJson.put("wifi_password", wifi_password);
        wifiToAddJson.put("latitude", wifi_LatLng.latitude);
        wifiToAddJson.put("longitude", wifi_LatLng.longitude);
        wifiToAddJson.put("name", name);
    } catch (JSONException e) {
        ACRA.getErrorReporter().handleSilentException(new MyJSONException(TAG + e.getMessage()));
    }
    return wifiToAddJson.toString();
}

我想通过询问所有字段'来测试这种方法是否正常。值。 我想用这样的测试做到这一点:

@Test
public void testSerialize(){
    String wifiSerialized = wiFiToAdd.serialize();

    try {
        JSONObject jsonObject = new JSONObject(wifiSerialized);

        String ssid = (String) jsonObject.get("wifi_ssid");
        String password = (String) jsonObject.get("wifi_password");
        String name = (String) jsonObject.get("name");
        String latitude = (String) jsonObject.get("latitude");
        String longitude = (String) jsonObject.get("longitude");

        assertEquals("WIFI_TEST", ssid);
        assertEquals("wifiTest", password);
        assertEquals("WiFi Pruebas", name);
        assertEquals("40.420088", latitude);
        assertEquals("-3.688810", longitude);

    } catch (JSONException e) {
        e.printStackTrace();
    }
}

但问题出现了:

java.lang.RuntimeException: Method put in org.json.JSONObject not mocked. See https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support for details.
    at org.json.JSONObject.put(JSONObject.java)
    at com.wiffinity.easyaccess.model.wifi.WiFiToAdd.serialize(WiFiToAdd.java:32)
    at com.wiffinity.easyaccess.model.wifi.WiFiToAddTest.testSerialize(WiFiToAddTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)


Process finished with exit code -1

Google文档说:

用于运行单元测试的android.jar文件不包含任何实际代码 - 由真实设备上的Android系统映像提供。相反,所有方法都抛出异常(默认情况下)。这是为了确保您的单元测试仅测试您的代码,并且不依赖于Android平台的任何特定行为(您没有明确嘲笑,例如使用Mockito)。如果证明有问题,可以将下面的代码段添加到build.gradle中以更改此行为:

android {
// ...

    testOptions { 
        unitTests.returnDefaultValues = true
    }
}

我不想改变测试的总体行为。如何以干净的方式测试方法而不改变测试的行为?

2 个答案:

答案 0 :(得分:1)

您可以在2中删除serialize方法:

public void serializeInto(JSONObject target) throws JSONException {
    wifiToAddJson.put("wifi_ssid", wifi_ssid);
    wifiToAddJson.put("wifi_password", wifi_password);
    wifiToAddJson.put("latitude", wifi_LatLng.latitude);
    wifiToAddJson.put("longitude", wifi_LatLng.longitude);
    wifiToAddJson.put("name", name);
}

public String serialize(){
    JSONObject wifiToAddJson = null;
    try {
        wifiToAddJson = new JSONObject();
        serializeInto(wifiToAddJson);
    } catch (JSONException e) {
        ACRA.getErrorReporter().handleSilentException(new MyJSONException(TAG + e.getMessage()));
    }
    return wifiToAddJson.toString();
}

然后用模拟JSONObject测试第一个,用模拟你的类测试第二个(只是验证方法serialize被调用)。

我对这个答案并不完全满意,因为你没有达到100%的覆盖率,我觉得它会降低代码的可读性。

答案 1 :(得分:1)

将其添加到build.gradle文件中:

testCompile 'org.json:json:20160810' // org.json is included with Android, but Android.jar can not be used from unit tests

它将使您的单元测试直接使用JSON库,而不是Android中包含的那个。

有关详细信息,请参阅this StackOverflow answer