我正在尝试为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;
}
任何帮助将不胜感激。
最佳答案
您的测试中有两个问题:
在实际交互之前,必须先配置呼叫存根。因此,只需交换这些行:
dataHandler.dataProcessor(json, topic_name, partition);
when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); //stub parseDebeziumSchema
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
}