我在类中有这个方法,它在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
}
}
我不想改变测试的总体行为。如何以干净的方式测试方法而不改变测试的行为?
答案 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。