问题描述
我是 Salesforce 的新手,我正在尝试进行生产部署,但由于代码覆盖问题而失败。 这些是我写的顶点类:
HttpCallOut.apxc
public with sharing class HttpCallOut {
@future(callout=true)
public static void callService(string endpoint,string method,string body) {
try {
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:API_SERVICES' + endpoint);
request.setMethod(method);
request.setHeader('content-type','application/json');
request.setBody(body);
HttpResponse response = http.send(request);
if (response.getStatusCode() != 200) {
System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus() + ' ' + response.getBody());
throw new CustomException('Error calling endpoint ' + endpoint + 'Status Code: ' + response.getStatusCode() + 'Status: ' + response.getStatus()+ 'Response Body: ' + response.getStatus());
}
return;
} catch (CalloutException calloutException) {
throw new CustomException('Error in HttpCallOut callService: ',calloutException);
}
}
}
CustomException.Apxc
public class CustomException extends Exception {
}
HandleUpdateOnReturnrefundCase
public with sharing class HandleUpdateOnReturnrefundCase {
private HttpCallOut httpCallOut = new HttpCallOut();
@invocableMethod
public static void handleUpdateOnReturnrefundCase(List<Id> caseIds) {
List<Case> updatedCases = [select id,Decision__c,ZoroCaseIdentifier__c,Type,Description,Returnoptions__c from Case where Id in :caseIds];
Case updatedCase = updatedCases.get(0);
if((updatedCase.Decision__c == 'Approved' && updatedCase.Returnoptions__c != null) || updatedCase.Decision__c == 'Rejected') {
httpCallOut.callService(
'/salesforce-case-updated','POST',genPayload(updatedCase.id,updatedCase.ZoroCaseIdentifier__c,updatedCase.Type)
);
} else {
throw new CustomException('Cannot update the case,please fill all required fields');
}
update updatedCases;
}
private static String genPayload(Id caseId,String zoroCaseIdentifier,String caseType) {
CasePayload casePayload = new CasePayload();
casePayload.caseId = caseId;
casePayload.caseType = caseType;
casePayload.zoroCaseIdentifier = zoroCaseIdentifier;
return JSON.serialize(casePayload);
}
}
CasePayload.Apxc
public class CasePayload {
public Id caseId {
get { return caseId; }
set { caseId = value; }
}
public String zoroCaseIdentifier {
get { return zoroCaseIdentifier; }
set { zoroCaseIdentifier = value; }
}
public String caseType {
get { return caseType; }
set { caseType = value; }
}
}
对于上面的顶点类,我编写了测试用例:
HandleUpdateOnReturnrefundCaseTest
@isTest
private class HandleUpdateOnReturnrefundCaseTest {
static testMethod void testApprovedReturnrefundCase() {
Case mockCase = new Case();
mockCase.Type = 'Request Return';
insert mockCase;
Test.starttest();
Test.setMock(HttpCalloutMock.class,new HttpCalloutSuccesstest());
mockCase.Decision__c = 'Approved';
mockCase.Returnoptions__c = 'FOC without Returned Items';
update mockCase;
Test.stoptest();
List<Case> cases = [SELECT Id,Decision__c FROM Case WHERE Id = :mockCase.Id];
for (Case c : cases) {
system.assertEquals(c.Decision__c,mockCase.Decision__c);
}
}
static testMethod void testRejectedReturnrefundCase() {
Case mockCase = new Case();
mockCase.Type = 'Request Return';
insert mockCase;
Test.starttest();
Test.setMock(HttpCalloutMock.class,new HttpCalloutSuccesstest());
mockCase.Decision__c = 'Rejected';
update mockCase;
Test.stoptest();
List<Case> cases = [SELECT Id,mockCase.Decision__c);
}
}
static testMethod void testCaseApprovedWithoutReturnoptions() {
try
{
Case mockCase = new Case();
mockCase.Type = 'Request Return';
insert mockCase;
Test.starttest();
Test.setMock(HttpCalloutMock.class,new HttpCalloutSuccesstest());
mockCase.Decision__c = 'Approved';
mockCase.Returnoptions__c = null;
update mockCase;
Test.stoptest();
} catch (Exception e) {
System.assert(e.getMessage().contains('Please select Return Options before saving'),'message=' + e.getMessage());
}
}
static testMethod void testCaseUpdatedWithHttpError() {
try
{
Case mockCase = new Case();
mockCase.Type = 'Request Return';
insert mockCase;
Test.starttest();
Test.setMock(HttpCalloutMock.class,new HttpCalloutErrortest());
mockCase.Decision__c = 'Approved';
mockCase.Returnoptions__c = 'FOC without Returned Items';
update mockCase;
Test.stoptest();
} catch (Exception e) {
System.assert(e.getMessage().contains('Error calling endpoint /salesforce-case-updated'),'message=' + e.getMessage());
}
}
}
HttpCalloutSuccesstest
global class HttpCalloutSuccesstest implements HttpCalloutMock{
global HttpResponse respond(HTTPRequest req){
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type','application/json');
res.setBody('{"status":"success"}');
res.setStatusCode(200);
return res;
}
}
HttpCalloutErrorTest
@isTest
global class HttpCalloutErrorTest implements HttpCalloutMock{
global HttpResponse respond(HTTPRequest req){
HttpResponse res = new HttpResponse();
res.setStatusCode(500);
return res;
}
}
当我通过单击“运行所有测试”在沙箱中运行测试时 - 我看到海湾覆盖率为 92%。所以我做了出站设置并尝试部署到生产环境。
但是在 prod 中,当我验证入站更改集时,它抱怨代码覆盖率问题。
不确定我做错了什么?如果缺少测试用例,那么代码的哪一部分?
解决方法
所以测试通过,没有异常,“只是”代码覆盖问题?您在变更集中包含了测试吗?
这看起来应该是从 Flow/ProcessBuilder (InvocableMethod
) 调用的。您是否在包中包含了该流程?是否活跃?或者 Case 触发器(如果它是从触发器调用的)
或者让单元测试直接调用HandleUpdateOnReturnRefundCase.handleUpdateOnReturnRefundCase()
,不用“触发机制”。这是一个单元测试,而不是整个系统集成。独立的测试块和单独的组合,将帮助您解决任何错误。
如果您仍然无法弄清楚 - 刷新新沙箱,部署到它(没有单元测试运行)并继续在那里工作,检查调试日志等。