Mockito无法Mock equals()方法的可行替代方案咨询
解决SwaggerClient测试中SwaggerParseResult的equals()断言问题
方案1:用expectNextMatches()自定义匹配逻辑
不用依赖equals()方法,直接验证返回结果的核心业务属性,这是最直接的解决方案,也更贴合单元测试的核心目标——验证业务逻辑正确性,而非对象相等性。
示例代码:
StepVerifier.create(swaggerClient.findApplicationDoc()) .expectNextMatches(parseResult -> "order-service-api".equals(parseResult.getInfo().getTitle()) && "v2".equals(parseResult.getInfo().getVersion()) && parseResult.getPaths().containsKey("/api/orders") ) .verifyComplete();
方案2:结合AssertJ自定义断言匹配
如果需要更结构化的断言,可以用AssertJ的流式断言配合expectNext(),同样不需要依赖equals():
示例代码:
StepVerifier.create(swaggerClient.findApplicationDoc()) .expectNext(result -> { assertThat(result.getInfo()) .hasFieldOrPropertyWithValue("title", "order-service-api") .hasFieldOrPropertyWithValue("version", "v2"); assertThat(result.getPaths()).containsKey("/api/orders"); return true; // 返回true表示匹配成功 }) .verifyComplete();
方案3:构造极简真实SwaggerParseResult实例
如果SwaggerParseResult的字段可访问(有setter、构造器或builder),可以手动构造只包含测试所需核心属性的真实实例,避免mock复杂对象:
示例代码:
// 构造测试用的真实实例 Info testInfo = new Info(); testInfo.setTitle("order-service-api"); testInfo.setVersion("v2"); SwaggerParseResult expected = new SwaggerParseResult(); expected.setInfo(testInfo); expected.setPaths(Map.of("/api/orders", new Path())); // 直接用真实实例断言 StepVerifier.create(swaggerClient.findApplicationDoc()) .expectNext(expected) .verifyComplete();
方案4:让Mock的SwaggerDocParser返回真实实例
绕开mock SwaggerParseResult的环节,直接让SwaggerDocParser的mock返回你预先构造好的真实SwaggerParseResult(可以用测试用的Swagger JSON提前解析得到,或者手动构造):
示例代码:
// 用测试JSON构造真实结果(或手动构造) String testSwaggerJson = "{\"info\":{\"title\":\"order-service-api\",\"version\":\"v2\"},\"paths\":{\"/api/orders\":{}}}"; SwaggerParseResult expectedResult = new SwaggerDocParser().parse(testSwaggerJson); // Mock SwaggerDocParser返回该真实实例 SwaggerDocParser mockParser = Mockito.mock(SwaggerDocParser.class); Mockito.when(mockParser.parse(Mockito.anyString())).thenReturn(expectedResult); // 注入mock并测试 SwaggerClient client = new SwaggerClient(mockWebClient, mockParser); StepVerifier.create(client.findApplicationDoc()) .expectNext(expectedResult) .verifyComplete();
总结
优先选择方案1或2,它们不需要依赖对象的equals()实现,直接验证业务关键属性,测试更健壮、更聚焦业务逻辑。如果必须用对象匹配,方案3和4是更简洁的替代,避免mock大量Swagger内部类。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

