Mockito(Junit)无法遍历JSONArray对象



我正在尝试为类DataHandler编写一个单元测试.java这反过来又从SchemaParsor类调用parseDebeziumSchema方法。

此方法将字符串转换为JSONArray,但是当我尝试使用when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray);模拟它时,它会抛出java.lang.NoSuchMethodError:org.json.JSONArray.iterator((Ljava/util/Iterator异常。

完整的堆栈跟踪如下,我还附加了DataHandler类,DataHandlerTest类parseDebeziumSchema方法代码:

java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator;
at com.xoom.transformer.dbschemahandler.SchemaParsor.parseDebeziumSchema(SchemaParsor.java:43)
at com.xoom.transformer.utils.DataHandlerTest.testdataProcessor(DataHandlerTest.java:52)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

DataHandlerTest.java:

public class DataHandlerTest {
    @Mock
    private SchemaManager schemaManager;
    @InjectMocks
    private SchemaParsor schemaParsor;
    @InjectMocks
    private DataHandler dataHandler;
    //Variables
    private final String json = "{"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"string","optional":false,"field":"recipe_name"}],"optional":true,"name":"_0.0.0.160.Debezium_test.recipes.Value","field":"before"},{"type":"struct","fields":[{"type":"string","optional":false,"field":"recipe_name"}],"optional":true,"name":"_0.0.0.160.Debezium_test.recipes.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":true,"field":"version"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"server_id"},{"type":"int64","optional":false,"field":"ts_sec"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"boolean","optional":true,"default":false,"field":"snapshot"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"db"},{"type":"string","optional":true,"field":"table"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"}],"optional":false,"name":"_0.0.0.160.Debezium_test.recipes.Envelope"},"payload":{"before":null,"after":{"recipe_name":"Chicken"},"source":{"version":"0.8.2","name":"10.0.0.160","server_id":1,"ts_sec":1549019230,"gtid":null,"file":"bin.000035","pos":263,"row":0,"snapshot":false,"thread":28,"db":"Debezium_test","table":"recipes","query":null},"op":"c","ts_ms":1549019230377}}";
    private final String topic_name = "database.table";
    private final int partition = 1;
    //Creating JSONObject
    private Iterator iterator = null;
    private JSONArray jsonArray=new JSONArray();
    private JSONObject jsonObject=new JSONObject();
    @Test //(expected=Exception.class)
    public void testdataProcessor() throws JsonParseException, JSONException {
        jsonObject.put("field","recipe_name");
        jsonObject.put("type","string");
        jsonArray.put(jsonObject);
        dataHandler.dataProcessor(json, topic_name, partition);
        when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray);
        verify(dataHandler, Mockito.times(1)).dataProcessor(json, topic_name, partition);
    }
}

parseDebeziumSchema

public JSONArray parseDebeziumSchema(String json)throws JsonParseException{
    debezium_schema_arrjson=new JSONArray();
    try{
    System.out.println("==========Raw Json===="+json);
    JSONObject jsonObj=new JSONObject(json);
    if(jsonObj.length()>0){
    JSONObject schema_detail=jsonObj.getJSONObject("schema");
    System.out.println("==========schema_detail===="+schema_detail);
    JSONArray fields_json_arr=schema_detail.getJSONArray("fields");
    System.out.println("==========fields_json_arr===="+fields_json_arr);
    for(Object field_json_obj:fields_json_arr){
    System.out.println("======field_json_obj===={}"+field_json_obj);
    JSONObject jsonObject_field=jsonUtils.objectToJSONObject(field_json_obj);
    JSONArray fields_json_arr_in=(JSONArray)jsonObject_field.get("fields");
    for(Object j_obj:fields_json_arr_in){
    debezium_schema_json=new JSONObject();
    JSONObject jsonObject=jsonUtils.objectToJSONObject(j_obj);
    debezium_schema_json.put("type",jsonObject.get("type"));
    debezium_schema_json.put("field",jsonObject.get("field"));
    debezium_schema_arrjson.put(debezium_schema_json);
    }
    break;
    }
    }
    }
    catch(Exception ex){
    LOGGER.error("Cannot parse JSON for spring.application.json: "+json,ex);
    throw new JsonParseException("SchemaParsor.parseDebeziumSchema. Debezium schema parse error.");
    }
    return debezium_schema_arrjson;
    }

任何帮助将不胜感激。

测试中有两个问题:

  1. 必须在实际交互之前配置呼叫存根。因此,只需交换这些行:
dataHandler.dataProcessor(json, topic_name, partition);
when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); //stub parseDebeziumSchema
  1. Mockito.verify用于验证与模拟的交互。但在代码中,您正在验证对待测试对象的方法调用。您看不到此错误,因为您的代码在第 1 点中断。删除此行:
verify(dataHandler, Mockito.times(1)).dataProcessor(json, topic_name, partition);

总而言之,您的代码应如下所示。我还添加了验证,验证schemaParsor.parseDebeziumSchema(json)只调用一次

@Test
public void testdataProcessor() throws JsonParseException, JSONException {
    jsonObject.put("field","recipe_name");
    jsonObject.put("type","string");
    jsonArray.put(jsonObject);
    when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); //stub parseDebeziumSchema
    dataHandler.dataProcessor(json, topic_name, partition);
    verify(schemaParsor, times(1)).parseDebeziumSchema(json); //verify that parseDebeziumSchema is called exactly once
}

最新更新