【问题标题】:Issue deploying change set in salesforce prod - code coverage issue在 salesforce prod 中部署更改集的问题 - 代码覆盖率问题
【发布时间】:2021-06-17 17:21:36
【问题描述】:

作为 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;
  }
}

当我通过单击“运行所有测试”在沙盒中运行测试时 - 我看到海湾覆盖率为 92%。所以我做了出站设置并尝试部署到产品。

但在产品中,当我验证入站更改集时,它抱怨代码覆盖率问题。

不确定我做错了什么?如果缺少测试用例,那是代码的哪一部分?

【问题讨论】:

    标签: salesforce apex apex-code salesforce-lightning


    【解决方案1】:

    所以测试通过了,没有例外,“只是”代码覆盖率问题?您将测试包含在变更集中吗?

    这看起来应该是从 Flow/ProcessBuilder (InvocableMethod) 调用的。您是否在包中包含该流程?是活跃的吗?或 Case 触发器(如果它是从触发器调用的)

    或者直接进行单元测试调用HandleUpdateOnReturnRefundCase.handleUpdateOnReturnRefundCase(),没有“触发机制”。这是一个单元测试,而不是整个系统集成。单独测试块和单独组合,将帮助您解决任何错误。

    如果您仍然无法弄清楚 - 刷新新沙箱,部署到它(不运行单元测试)并继续在那里工作,检查调试日志等。

    【讨论】:

    • 感谢@eyescream,是的,我错过了一些流程及其依赖性。感谢您指出了这一点。非常感谢!
    猜你喜欢
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    相关资源
    最近更新 更多