You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Apex控制器DocumentSelectorController测试覆盖率提升至75%以上

提升DocumentSelectorController测试覆盖率的解决方案

核心问题分析

  1. getChildObjects方法仅覆盖到Id recordId = hostId;,说明未正确模拟依赖的元数据和Helper类返回结果,导致后续CreateRelatedSettingHelper.getCreateRelatedSetting、getSOQLQuery及Database.query逻辑未执行,直接进入catch块。
  2. releaseDocument和releaseChildDocuments包含大量switch分支与if条件,未覆盖所有分支路径是覆盖率不足的主要原因。

测试类编写关键步骤

  • 插入测试用自定义元数据:构造不同配置的dmpl__CreateRelatedSetting__mdt记录,覆盖所有HostObject、RelatedObject、Tag组合。
  • 构造业务对象测试数据:创建dmpl__SaleOrder__c、dmpl__InventoryFulfillment__c等业务对象的测试记录,满足Helper类方法的入参要求。
  • 覆盖正常与异常分支:既测试方法正常执行的场景,也模拟异常触发(如无效Id、空元数据)覆盖catch块。

完整测试类代码

@isTest
private class DocumentSelectorControllerTest {
    @testSetup
    static void setupTestData() {
        // 插入自定义元数据记录,覆盖不同分支场景
        insert new dmpl__CreateRelatedSetting__mdt(
            MasterLabel = 'SaleOrder to InventoryFulfillment',
            dmpl__HostObjectId__c = Schema.dmpl__SaleOrder__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__RelatedObjectId__c = Schema.dmpl__InventoryFulfillment__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__Tag__c = ''
        );

        insert new dmpl__CreateRelatedSetting__mdt(
            MasterLabel = 'SaleOrder OTC to SaleInvoice',
            dmpl__HostObjectId__c = Schema.dmpl__SaleOrder__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__RelatedObjectId__c = Schema.dmpl__SaleInvoice__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__Tag__c = 'OTC'
        );

        insert new dmpl__CreateRelatedSetting__mdt(
            MasterLabel = 'InventoryFulfillment to DeliveryOrder',
            dmpl__HostObjectId__c = Schema.dmpl__InventoryFulfillment__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__RelatedObjectId__c = Schema.dmpl__DeliveryOrder__c.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__Tag__c = ''
        );

        // 插入业务对象测试记录
        dmpl__SaleOrder__c testOrder = new dmpl__SaleOrder__c(Name = 'Test Order 001');
        insert testOrder;

        dmpl__InventoryFulfillment__c testFulfillment = new dmpl__InventoryFulfillment__c(
            Name = 'Test Fulfillment 001',
            dmpl__SaleOrder__c = testOrder.Id
        );
        insert testFulfillment;
    }

    static testMethod void testGetCreateRelatedSettings() {
        // 测试正常场景
        Test.startTest();
        List<dmpl__CreateRelatedSetting__mdt> settings = DocumentSelectorController.getCreateRelatedSettings('dmpl__SaleOrder__c');
        Test.stopTest();
        System.assertNotEquals(null, settings);

        // 测试异常场景
        Test.startTest();
        try {
            DocumentSelectorController.getCreateRelatedSettings('InvalidObject');
            System.assert(false, 'Expected exception not thrown');
        } catch (Exception e) {
            System.assert(true);
        }
        Test.stopTest();
    }

    static testMethod void testGetChildObjects() {
        // 获取测试元数据Id
        dmpl__CreateRelatedSetting__mdt testSetting = [SELECT Id FROM dmpl__CreateRelatedSetting__mdt WHERE MasterLabel = 'SaleOrder to InventoryFulfillment'];
        dmpl__SaleOrder__c testOrder = [SELECT Id FROM dmpl__SaleOrder__c LIMIT 1];

        // 测试正常场景(假设CreateRelatedSettingHelper.getSOQLQuery返回合法查询)
        Test.startTest();
        List<SObject> childObjects = DocumentSelectorController.getChildObjects(testSetting.Id, testOrder.Id, 'Test');
        Test.stopTest();
        System.assertNotEquals(null, childObjects);

        // 测试异常场景(无效元数据Id)
        Test.startTest();
        try {
            DocumentSelectorController.getChildObjects('000000000000000AAA', testOrder.Id, 'Test');
            System.assert(false, 'Expected exception not thrown');
        } catch (Exception e) {
            System.assert(true);
        }
        Test.stopTest();
    }

    static testMethod void testReleaseDocument() {
        // 测试SaleOrder -> InventoryFulfillment分支
        dmpl__CreateRelatedSetting__mdt setting1 = [SELECT Id FROM dmpl__CreateRelatedSetting__mdt WHERE MasterLabel = 'SaleOrder to InventoryFulfillment'];
        dmpl__SaleOrder__c testOrder = [SELECT Id FROM dmpl__SaleOrder__c LIMIT 1];
        Test.startTest();
        CreateRelatedResult result1 = DocumentSelectorController.releaseDocument(setting1.Id, testOrder.Id);
        Test.stopTest();
        System.assertNotEquals(null, result1);

        // 测试SaleOrder OTC -> SaleInvoice分支
        dmpl__CreateRelatedSetting__mdt setting2 = [SELECT Id FROM dmpl__CreateRelatedSetting__mdt WHERE MasterLabel = 'SaleOrder OTC to SaleInvoice'];
        Test.startTest();
        CreateRelatedResult result2 = DocumentSelectorController.releaseDocument(setting2.Id, testOrder.Id);
        Test.stopTest();
        System.assertNotEquals(null, result2);

        // 测试InventoryFulfillment -> DeliveryOrder分支
        dmpl__CreateRelatedSetting__mdt setting3 = [SELECT Id FROM dmpl__CreateRelatedSetting__mdt WHERE MasterLabel = 'InventoryFulfillment to DeliveryOrder'];
        dmpl__InventoryFulfillment__c testFulfillment = [SELECT Id FROM dmpl__InventoryFulfillment__c LIMIT 1];
        Test.startTest();
        CreateRelatedResult result3 = DocumentSelectorController.releaseDocument(setting3.Id, testFulfillment.Id);
        Test.stopTest();
        System.assertNotEquals(null, result3);

        // 测试无匹配分支场景
        dmpl__CreateRelatedSetting__mdt setting4 = new dmpl__CreateRelatedSetting__mdt(
            MasterLabel = 'Unmatched Setting',
            dmpl__HostObjectId__c = Schema.Account.SObjectType.getDescribe().getKeyPrefix(),
            dmpl__RelatedObjectId__c = Schema.Contact.SObjectType.getDescribe().getKeyPrefix()
        );
        insert setting4;
        Test.startTest();
        CreateRelatedResult result4 = DocumentSelectorController.releaseDocument(setting4.Id, testOrder.Id);
        Test.stopTest();
        System.assertEquals('No handler attached', result4.Message);

        // 测试异常场景
        Test.startTest();
        try {
            DocumentSelectorController.releaseDocument('000000000000000AAA', testOrder.Id);
            System.assert(false, 'Expected exception not thrown');
        } catch (Exception e) {
            System.assert(true);
        }
        Test.stopTest();
    }

    static testMethod void testReleaseChildDocuments() {
        // 构造测试用SourceObjectInfo列表
        List<SourceObjectInfo> testChildInfo = new List<SourceObjectInfo>{
            new SourceObjectInfo(Id = [SELECT Id FROM dmpl__SaleOrder__c LIMIT 1].Id, Name = 'Test Line')
        };

        // 测试SaleOrder -> InventoryFulfillment分支
        dmpl__CreateRelatedSetting__mdt setting1 = [SELECT Id FROM dmpl__CreateRelatedSetting__mdt WHERE MasterLabel = 'SaleOrder to InventoryFulfillment'];
        dmpl__SaleOrder__c testOrder = [SELECT Id FROM dmpl__SaleOrder__c LIMIT 1];
        Test.startTest();
        CreateRelatedResult result1 = DocumentSelectorController.releaseChildDocuments(testOrder.Id, setting1.Id, testChildInfo);
        Test.stopTest();
        System.assertNotEquals(null, result1);

        // 测试异常场景
        Test.startTest();
        try {
            DocumentSelectorController.releaseChildDocuments(testOrder.Id, '000000000000000AAA', testChildInfo);
            System.assert(false, 'Expected exception not thrown');
        } catch (Exception e) {
            System.assert(true);
        }
        Test.stopTest();
    }

    // 模拟SourceObjectInfo类(测试中需要)
    private class SourceObjectInfo {
        public Id Id { get; set; }
        public String Name { get; set; }
    }

    // 模拟CreateRelatedResult类(测试中需要)
    private class CreateRelatedResult {
        public String Message { get; set; }
        public Boolean IsSuccess { get; set; }

        public CreateRelatedResult(String message) {
            this.Message = message;
            this.IsSuccess = false;
        }
    }
}

额外注意事项

  • 如果CreateRelatedSettingHelper等依赖类逻辑复杂,可使用Mock类(如System.StubProvider)隔离依赖,避免测试受Helper类内部逻辑影响。
  • 确保所有自定义对象和元数据的API名称与生产环境一致,避免因命名错误导致测试失败。
  • 针对releaseChildDocuments的剩余分支,参照上述测试逻辑,补充对应元数据和测试用例即可覆盖。

内容的提问来源于stack exchange,提问作者Mandeep Kaur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:03:19