Mockito(Junit)无法通过JSONArray对象进行迭代

时间:2019-02-07 09:19:00

标签: java exception junit mockito

我正在尝试为DataHandler.java类编写单元测试,这又从SchemaParsor类调用了 parseDebeziumSchema 方法。

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

完整的堆栈跟踪如下,此外,我还附加了 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 个答案:

答案 0 :(得分:2)

测试中有两个问题:

  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
}