尝试在 salesforce apex 中创建测试类并以 100% 代码覆盖率通过

问题描述 投票:0回答:1

Salesforce Apex,测试类:

我正在尝试创建一个 TestClass 并在 apex 中为批处理脚本实现 100% 的代码覆盖率。我正在测试的类如下所示:

    public class UpdateContractStatusBatch implements Database.Batchable<sObject>, Schedulable {
        public Database.QueryLocator start(Database.BatchableContext BC) {
        String query = 'SELECT Id, Status__c, SBQQ__RenewalForecast__c FROM Contract WHERE Status__c = \'Activated\' AND Legacy_Contract__c = false';
        return Database.getQueryLocator(query);
        }
        public void execute(Database.BatchableContext BC, List<Contract> scope) {
        if (scope.size()==0){
           return;
        }

        List<Contract> contractsToUpdate = new List<Contract>();
        List<Database.SaveResult> results;

        try {
            for(Contract con : scope) {
                con.Status__c = 'Renewal Forecasted';
                con.SBQQ__RenewalForecast__c = true;
                contractsToUpdate.add(con);
            }

            results = Database.update(contractsToUpdate, false);
        
        } catch (Exception e) {
            System.debug('Exception in batch execute: ' + e.getMessage());
        }

        for (Database.SaveResult sr : results) {
            if(!sr.isSuccess()) {
                for(Database.Error err : sr.getErrors()) {
                    System.debug('Error updating contract Id: ' + sr.getId() + ' - ' + err.getMessage());
                }
            }
        }
    }

        for (Database.SaveResult sr : results) {
            if(!sr.isSuccess()) {
                 for(Database.Error err : sr.getErrors()) {
                      System.debug('Error updating contact ID: ' + sr.getId() + ' - ' + err.getMessage());
        }
       }
      }
     }

     public void finish(Database.BatchableContext BC) {
     }

     public void execute(SchedulableContext sc) {
           Database.execueBatch(new UpdateContractStatusBatch());
     }
}

这是我迄今为止实现 76% 代码覆盖率的测试类:

@isTest
private class UpdateContractsStatusBatchTest{

    @isTest
    static void testBatch(){
        // Create admin user
        Profile adminProfile = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        User adminUser = new User(
            Alias = 'admin',
            Email = '[email protected]',
            EmailEncodingKey = 'UTF-8',
            LastName = 'Admin',
            LanguageLocalKey = 'en_US',
            LocaleSidKey = 'en_US',
            ProfileId = adminProfile.Id,
            TimeZoneSidKey = 'America/Los_Angeles',
            UserName = '[email protected]',
            ByPassValidation__c = true
        );
        insert adminUser;

        // Run the test as athe admin user
        System.runAs(adminUser) {
            // create product
            Product2 sp = new Product2(
                Name = 'Test Subscription',
                IsActive = true,
                SBQQ__PricingMethod__c = 'List',
                SBQQ__SubscriptionPricing__c = 'Fixed Price',
                SBQQ__SubscriptionTerm__c = 12,
                Status__c = 'Draft'
            );
            insert sp;

            Id pbid = Test.getStandardPriceBookId();
            PricebookEntry spbe = new PricebookEntry(Product2Id = sp.id, Pricebook2Id = pbid, UnitPrice = 1, IsActive = true);
            insert spbe;

            // Create Account
            Account a = new Account(Name = 'Test Account', BillingCity = 'St Albans');
            insert a;

            //Create Opps
            Opportunity o = new Opportunity(
                AccountId = a.Id,
                Name = 'Test Opps',
                StageName = 'Qualification',
                CloseDate = Date.today(),
                Pricebook2Id = pbid,
                CurrencyIsoCode = 'USD',
                Deal_Type__c = 'Direct',
                Direct_Customer_Sales_Channel__c = 'Direct'
            );
            insert o;

            // Create Quote
            SBQQ__Quote___c q = new SBQQ__Quote___c(
                SBQQ__Account__c = a.Id,
                SBQQ__Opportunity2__c = o.Id,
                SBQQ__Type__c = 'Quote',
                SBQQ__Primary__c = true,
                SBQQ__Pricebook__c = pbid,
                SBQQ__StartDate__c = Date.today(),
                SBQQ__EndDate__c = Date.today() + 365,
                Deal_Type__c = 'Direct',
                Sales_Channel__c = 'Direct',
                SBQQ__SubscriptionTerm__c = 12,
                SBQQ__Renewal__c = 8
            );
            insert q;

            // Create Quote Line
            SBQQ__QuoteLine__c sql = new SBQQ__QuoteLine__c (
                SBQQ__Quote__c = q.Id,
                SBQQ__Product__c = sp.Id,
                SBQQ__Quanity__c = 1,
                SBQQ__SubscriptionPricing__c = 'Fixed Price',
                SBQQ__ProductSubscriptionType__c = 'Renewable',
                SBQQ__SubscriptionType__c = 'Renewable',
                SBQQ__DefaultSubscriptionTerm__c = 12,
                SBQQ__SubscriptionTerm__c = 12,
                SBQQ__StartDate__c = Date.today()
            );
            insert sql;

            // Create Legacy_Contract__c = true
            Contract c1 = new Contract(
                AccountId = a.Id,
                SBQQ__Opportunity__c = o.Id,
                SBQQ__Quote__c = q.Id,
                Status__c = 'Draft',
                StartDate__c = Date.today(),
                ContractTerm = 12,
                Legacy_Contract__c = true,
                SBQQ__PreserveBundlesStructureUponRenewals__c = true
            );
            insert c1;


            // Create Legacy_Contract__c = false
            Contract c2 = new Contract(
                AccountId = a.Id,
                SBQQ__Opportunity__c = o.Id,
                SBQQ__Quote__c = q.Id,
                Status__c = 'Draft',
                StartDate__c = Date.today(),
                ContractTerm = 12,
                Legacy_Contract__c = false,
                SBQQ__PreserveBundlesStructureUponRenewals__c = true
            );
            insert c2;


            //Create Subscription
            SBQQ__Subscription__c = new SBQQ__Subscription__c(
                SBQQ__Account__c = a.Id,
                SBQQ__Contract__c = c2.Id,
                SBQQ__Product__c = sp.Id,
                SBQQ__QuoteLine__c = sql.Id,
                SBQQ__Quanity__c = 1,
                SBQQ__ListPrice__c = 1,
                SBQQ__NetPrice__c = 1,
                SBQQ__CustomerPrice__c = 1,
                SBQQ__RenewalQuantity__c = 1
            );
            insert s;

            // Enque the batch
            Test.startTest();
            UpdateContractsStatusBatch batch = new UpdateContractsStatusBatch();
            Database.executeBatch(batch);
            Test.stopTest();

            // Verify that the contracts were updated
            List<Contract> updateContractsC1 = [SELECT Id, Status__c, SBQQ__RenewalForecast__c FROM Contract WHERE Id = :c2.Id];
            System.assertEquals('Renewal Forecasted', updatedContractsC1[0].Status__c, 'Contract is updated');
            System.assertEquals(true, updatedContractsC1[0].SBQQ__RenewalForecast__c, 'Renewal Forecast must be true');


// Verify that the contracts were updated
            List<Contract> updateContractsC2 = [SELECT Id, Status__c, SBQQ__RenewalForecast__c FROM Contract WHERE Id = :c2.Id];
            System.assertEquals('Renewal Forecasted', updatedContractsC2[0].Status__c, 'Contract is updated');
            System.assertEquals(true, updatedContractsC2[0].SBQQ__RenewalForecast__c, 'Renewal Forecast must be true');
        }
    }
}

课程中未涵盖的线路有:

Line 10:    Return;

Line 24:    } catch (Exception e){

Line 30:    public void execute(SchedulableContext sc) {
                  Database.executeBatch(new UpdateContractStatusBatch());

100% 的代码覆盖率是我所追求的。预先感谢!

unit-testing salesforce apex
1个回答
0
投票
if (scope.size()==0){
    return;
}

这是无法访问的代码。如果剩余记录为零 - 它甚至不会调用上次的execute()。删除它。

try {
    for(Contract con : scope) {
        con.Status__c = 'Renewal Forecasted';
        con.SBQQ__RenewalForecast__c = true;
        contractsToUpdate.add(con);
    }

    results = Database.update(contractsToUpdate, false);

} catch (Exception e) {
    System.debug('Exception in batch execute: ' + e.getMessage());
}

这也是相当遥不可及的。您使用的是不引发异常的

Database.update
版本。在更复杂的代码中,您可能会遇到一些数学错误(除以零或诸如“5 + null = 引发异常”之类的内容),但我们看到的看起来非常安全。

这些调试非常弱。一旦你过了最初的开发阶段,我就会删除它们并阅读有关

Database.RaisesPlatformEvents
的内容。

public void execute(SchedulableContext sc) {

您可以通过显式调用该方法来解决此问题,

new UpdateContractStatusBatch().execute(null);
或检查https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler中的“测试Apex Scheduler”。嗯

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.