salesforce apex测试类如果有多个httpmock,则只会返回一个,导致可能不符合预期
在 Salesforce Apex 的测试类中,当需要模拟多个不同的 HTTP 响应时,可以使用 HttpCalloutMock
接口并实现逻辑来区分不同的 HTTP 请求并返回不同的响应。
如果多个 HTTP 请求都使用同一个 HttpCalloutMock
实例,而没有区分逻辑,则只会返回一个默认的响应,这可能会导致测试结果不符合预期。
解决方法:自定义 Mock 逻辑
通过实现自定义的 HttpCalloutMock
,根据请求的 URL 或其他信息区分不同的 HTTP 请求,返回相应的响应。
以下是一个示例代码:
@isTest
public class MultiHttpMockTest {
// 自定义 HttpMock 类
public class CustomHttpCalloutMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
// 根据请求的 URL 或 Body 区分不同的响应
if (req.getEndpoint().contains('https://example.com/api1')) {
res.setStatusCode(200);
res.setBody('{"result": "Response for API 1"}');
} else if (req.getEndpoint().contains('https://example.com/api2')) {
res.setStatusCode(200);
res.setBody('{"result": "Response for API 2"}');
} else {
res.setStatusCode(404);
res.setBody('{"error": "Not Found"}');
}
return res;
}
}
@isTest
static void testMultipleCallouts() {
// 设置自定义 HttpMock
Test.setMock(HttpCalloutMock.class, new CustomHttpCalloutMock());
// 模拟第一个 API 调用
HttpRequest req1 = new HttpRequest();
req1.setEndpoint('https://example.com/api1');
req1.setMethod('GET');
HttpResponse res1 = new Http().send(req1);
System.assertEquals(200, res1.getStatusCode());
System.assert(res1.getBody().contains('Response for API 1'));
// 模拟第二个 API 调用
HttpRequest req2 = new HttpRequest();
req2.setEndpoint('https://example.com/api2');
req2.setMethod('GET');
HttpResponse res2 = new Http().send(req2);
System.assertEquals(200, res2.getStatusCode());
System.assert(res2.getBody().contains('Response for API 2'));
}
}
核心思路
- 自定义
HttpCalloutMock
:实现HttpCalloutMock
接口,在respond
方法中根据请求的内容返回不同的响应。 - 使用区分条件:通过
req.getEndpoint()
、req.getBody()
或其他属性区分请求。 - 设置 Mock:使用
Test.setMock()
方法设置自定义的HttpCalloutMock
。 - 在测试中验证:通过
HttpResponse
验证每次 HTTP 调用返回的内容是否符合预期。
注意事项
- 确保请求的区分逻辑准确:避免因为相似的条件导致错误的响应。
- 覆盖所有测试场景:为每种可能的请求配置对应的响应,确保测试的完整性。
- 验证 HTTP 响应内容:不仅要验证状态码,还要验证响应的主体是否符合预期。
这种方式可以确保在测试类中正确模拟多个 HTTP 请求和响应。