一个模拟的类工作正常,另一个返回null

我正在其中一个单元测试中模拟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调用可以按预期工作的事实告诉我其他事情正在发生。

zhi_huiyudi 回答:一个模拟的类工作正常,另一个返回null

如果JSONObject的包是org.json,则JSONObject的equals方法如下:

public boolean equals(Object object) {
            return object == null || object == this;
        }

由于matchesArrayQueryService的实例与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)

本文链接:https://www.f2er.com/3157949.html

大家都在问