我正在其中一个单元测试中模拟2个类,以定义Mockito的行为。何时再调用函数。
其中一个模拟的类完全按预期工作,另一个返回null
。我不知道两者之间有什么区别。
QueryServiceTest.java
@Import({ QueryServiceTestConfig.class })
@RunWith(SpringRunner.class)
public class QueryServiceTest {
@Autowired
private QueryService queryService;
@MockBean
private ElasticConnectionService elasticConnectionService;
@MockBean
private HBaseConnectionService hbaseConnectionService;
@Test
public void test_getRecordsFromQuery() throws IOException {
// creation of sample data for inputs and outputs goes here
// This mock works when called from queryService.getRecordsFromQuery()
when(elasticConnectionService.getRowIdsFromQuery(filterParams, testIndex)).thenReturn(getRowIdsFromQuery_result);
List<JSONObject> matches = queryService.getMatchingRowIds(getRowIdsFromQuery_result);
// matchesArray is directly defined to make sure its exactly the same as in queryService.getRecordsFromQuery()
JSONObject matchesArray = new JSONObject("{\"testTable\":[\"testUUID\"]}");
// This mock fails when called from queryService.getRecordsFromQuery()
when(hbaseConnectionService.getRowsByIDs(matchesArray)).thenReturn(getRowsByIDs_result);
// This returns getRowsByIDs_result as expected
JSONArray test = hbaseConnectionService.getRowsByIDs(matchesArray);
// This returns null
JSONArray actual = new JSONArray(queryService.getRecordsFromQuery(filterParams, testIndex));
}
}
QueryService.java
@Service
public class QueryService {
@Autowired
private ElasticConnectionService elasticConnectionService;
@Autowired
private HBaseConnectionService hbaseConnectionService;
@Autowired
private PSQLConnectionService psqlConnectionService;
public String getRecordsFromQuery(
Map<String,String> filterParams,
String tablename) throws IOException {
/**
* Get records that match simple key/value filters
*/
// This mocked method returns exactly what was expected
List<List<JSONObject>> lookupsList = elasticConnectionService.getRowIdsFromQuery(filterParams, tablename);
List<JSONObject> matches = getMatchingRowIds(lookupsList);
// matchesArray is exactly the same as in the test class
JSONObject matchesArray = new JSONObject("{\"testTable\":[\"testUUID\"]}");
// This returns null
JSONArray hbResults = hbaseConnectionService.getRowsByIDs(matchesArray);
return hbResults.toString(4);
}
}
QueryServiceTestConfig.java
@Configuration
public class QueryServiceTestConfig {
@Bean
public QueryService queryService() {
return new QueryService();
}
@Bean
public ElasticConnectionService elasticConnectionService() {
return new ElasticConnectionService();
}
@Bean
public HBaseConnectionService hbaseConnectionService() {
return new HBaseConnectionService();
}
@Bean
public PSQLConnectionService psqlConnectionService() {
return new PSQLConnectionService();
}
}
最让我困惑的是,在queryService.getRecordsByQuery()
中,elasticConnectionService.getRowIDsFromQuery()
模拟返回了预期的结果,但是hbaseConnectionService.getRowsByIDs()
模拟返回了null
。
弹性和hbase连接服务类都在同一文件夹中定义,并且它们具有的唯一注释是@Service
。我想如果两个都失败了,我会配置错误,但是elasticConnectionService
调用可以按预期工作的事实告诉我其他事情正在发生。
答案 0 :(得分:1)
如果JSONObject
的包是org.json
,则JSONObject
的equals方法如下:
public boolean equals(Object object) {
return object == null || object == this;
}
由于matchesArray
中QueryService
的实例与QueryServiceTest
中的实例不同,因此equals()
方法将返回false。
尝试更改此内容:
when(hbaseConnectionService.getRowsByIDs(matchesArray)).thenReturn(getRowsByIDs_result);
对此,并查看您的结果是否更改:
when(hbaseConnectionService.getRowsByIDs(Mockito.any())).thenReturn(getRowsByIDs_result);
我认为您也可以这样做:
when(hbaseConnectionService.getRowsByIDs(Mockito.eq(matchesArray))).thenReturn(getRowsByIDs_result);
或:
when(hbaseConnectionService.getRowsByIDs(Matchers.eq(matchesArray))).thenReturn(getRowsByIDs_result);
由于在后台,Matchers.eq()
方法可能调用JSONObject.equals()
,所以Matcher可能无法工作(我没有检查Matchers.eq()
的源代码)。
通常,在设置模拟方法调用时,您希望将parameter(s)
包装在Mockito的Matcher的方法之一中。不幸的是,这不适用于您的情况。
(请注意,Mockito类扩展了Matchers)