在 salesforce 产品中部署变更集的问题 - 代码覆盖问题
Issue deploying change set in salesforce prod - code coverage issue
作为 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, Decision__c FROM Case WHERE Id = :mockCase.Id];
for (Case c : cases) {
system.assertEquals(c.Decision__c, 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;
}
}
当我 运行 通过单击“运行 所有测试”在沙箱中进行测试时 - 我看到 cove 覆盖率为 92%。所以我做了出站设置并尝试部署到产品。
但是在产品中,当我验证入站更改集时,它抱怨代码代码覆盖问题。
不确定我做错了什么?如果缺少测试用例,那么代码的哪一部分?
所以测试通过了,没有异常,“只是”代码覆盖问题?您在变更集中包含了测试?
这看起来应该从 Flow/ProcessBuilder (InvocableMethod
) 中调用。您是否将该流程包含在包裹中?活跃吗?或者 Case 触发器(如果它是从触发器调用的)
或者直接让单元测试调用 HandleUpdateOnReturnRefundCase.handleUpdateOnReturnRefundCase()
,没有“触发机制”。这是一个单元测试,而不是整个系统集成。独立测试块和单独组合,将帮助您纠正任何错误。
如果您仍然无法弄清楚 - 刷新新沙箱,部署到它(没有单元测试 运行)并继续在那里工作,检查调试日志等。
作为 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, Decision__c FROM Case WHERE Id = :mockCase.Id];
for (Case c : cases) {
system.assertEquals(c.Decision__c, 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;
}
}
当我 运行 通过单击“运行 所有测试”在沙箱中进行测试时 - 我看到 cove 覆盖率为 92%。所以我做了出站设置并尝试部署到产品。
但是在产品中,当我验证入站更改集时,它抱怨代码代码覆盖问题。
不确定我做错了什么?如果缺少测试用例,那么代码的哪一部分?
所以测试通过了,没有异常,“只是”代码覆盖问题?您在变更集中包含了测试?
这看起来应该从 Flow/ProcessBuilder (InvocableMethod
) 中调用。您是否将该流程包含在包裹中?活跃吗?或者 Case 触发器(如果它是从触发器调用的)
或者直接让单元测试调用 HandleUpdateOnReturnRefundCase.handleUpdateOnReturnRefundCase()
,没有“触发机制”。这是一个单元测试,而不是整个系统集成。独立测试块和单独组合,将帮助您纠正任何错误。
如果您仍然无法弄清楚 - 刷新新沙箱,部署到它(没有单元测试 运行)并继续在那里工作,检查调试日志等。