我正在尝试为类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
}