如何格式化JSONObject单元测试,解决空指针与期望异常不符问题?
单元测试预期抛出IllegalStateException却触发NullPointerException的解决方法
在对sendCommand方法执行单元测试时,预期抛出IllegalStateException,但实际触发了NullPointerException。异常发生在sendCommand方法的switch语句处,相关代码与错误信息如下:
单元测试代码
@Test(expected = IllegalStateException.class) public void shouldThrowIllegalStateExceptionOnUnknownCommand() { try { JSONObject test = new JSONObject(); test.put("name", "UnitTest"); test.put("payload", "{ \"example\": \"payload\" }"); testClassObject.sendCommand(test); } catch (JSONException e) { Log.e(TAG, "failed to parse JSON Object Unit test" + e.getMessage()); } }
sendCommand方法代码
public void sendCommand(JSONObject reader) { try { String commandName = reader.getString("name"); JSONObject data = reader.getJSONObject("payload"); switch (commandName) { case "ValidCommand": //Do Stuff break; default: Log.i(TAG, "Unknown command"); throw new IllegalStateException("Unknown command: " + commandName); } } catch (JSONException e) { Log.e(TAG, " Failed to parse JSON Object / array " + e.getMessage()); } }
错误信息
Unexpected exception, expected<java.lang.IllegalStateException> but was<java.lang.NullPointerException> java.lang.Exception: Unexpected exception, expected<java.lang.IllegalStateException> but was<java.lang.NullPointerException> at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
问题原因
测试代码中给payload赋值了一个JSON格式的字符串,但sendCommand方法里调用reader.getJSONObject("payload")时,会尝试将这个字符串解析为JSONObject,这会触发JSONException。而sendCommand的catch块仅打印日志,没有重新抛出异常,后续代码继续执行时,commandName变量因异常流程未被正确初始化,进入switch语句时触发NullPointerException。
解决方法
给payload直接赋值一个JSONObject实例,而非JSON字符串。修改后的单元测试代码如下:
@Test(expected = IllegalStateException.class) public void shouldThrowIllegalStateExceptionOnUnknownCommand() { try { JSONObject test = new JSONObject(); test.put("name", "UnitTest"); // 直接构造JSONObject作为payload的值 JSONObject payload = new JSONObject(); payload.put("example", "payload"); test.put("payload", payload); testClassObject.sendCommand(test); } catch (JSONException e) { Log.e(TAG, "failed to parse JSON Object Unit test" + e.getMessage()); } }
此外,建议在sendCommand方法的catch块中重新抛出异常(或处理异常后终止流程),避免因异常被吞掉导致后续代码执行出现意外问题。
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

