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

如何通过Apex代码为Apex测试类创建或控制Duplicate/Matching规则

解决方案

首先明确:Apex 原生不支持通过 DML 直接创建/激活/停用重复规则(DuplicateRule)和匹配规则(MatchingRule),这两类属于元数据对象,仅能通过元数据接口操作,而测试上下文内元数据变更不会即时生效,因此你最初提出的两个需求没有可落地的原生实现路径。

以下是两种可实现全量测试覆盖率的可行方案:

方案1:依赖注入+逻辑拆分(最推荐,无环境依赖)

将重复结果处理逻辑从DML调用部分抽离为独立的可测方法,测试时直接手动构造Datacloud.DuplicateResult对象传入即可,不需要真实触发重复规则:

  1. 重构业务代码,拆分核心逻辑:
public class DuplicateCheckApi {
    // 原有对外暴露的接口
    public List<DuplicateCheckResult> createRecords(List<SObject> records) {
        List<Database.SaveResult> saveResults = Database.insert(records, false);
        List<DuplicateCheckResult> output = new List<DuplicateCheckResult>();
        for(Integer i=0; i<saveResults.size(); i++) {
            Database.SaveResult sr = saveResults[i];
            if(!sr.isSuccess()) {
                for(Database.Error err : sr.getErrors()) {
                    if(err instanceof Database.DuplicateError) {
                        // 抽离重复处理逻辑
                        output.add(processDuplicateError(
                            (Database.DuplicateError)err, 
                            records[i]
                        ));
                    }
                }
            }
        }
        return output;
    }

    // 独立的重复结果处理方法,可直接测试
    @TestVisible
    private DuplicateCheckResult processDuplicateError(Database.DuplicateError err, SObject inputRecord) {
        // 你的原有重复处理逻辑,比如读取匹配记录、返回错误提示等
        Datacloud.DuplicateResult dupRes = err.getDuplicateResult();
        DuplicateCheckResult result = new DuplicateCheckResult();
        result.isDuplicate = true;
        result.duplicateRecordIds = dupRes.getDuplicateRecordIds();
        result.inputRecord = inputRecord;
        return result;
    }
}
  1. 测试类直接构造测试数据覆盖核心逻辑:
@isTest
private class DuplicateCheckApiTest {
    @isTest
    static void testDuplicateProcess() {
        // 手动构造重复错误和结果
        Datacloud.MatchResult matchRes = new Datacloud.MatchResult();
        matchRes.setMatchConfidence(95);
        matchRes.setEntityType('Account');
        // 可提前插入一条测试用的存量账户获取ID
        Account testExistAcc = new Account(Name='存量测试客户');
        insert testExistAcc;
        matchRes.setRecordIds(new List<Id>{testExistAcc.Id});

        Datacloud.DuplicateResult dupRes = new Datacloud.DuplicateResult();
        dupRes.setMatchResults(new List<Datacloud.MatchResult>{matchRes});
        dupRes.setIsSuccess(true);

        Database.DuplicateError mockError = new Database.DuplicateError(dupRes);

        Account testInputAcc = new Account(Name='测试重复客户');
        Test.startTest();
        DuplicateCheckResult result = new DuplicateCheckApi().processDuplicateError(mockError, testInputAcc);
        Test.stopTest();

        // 断言逻辑符合预期
        System.assertEquals(true, result.isDuplicate);
        System.assertEquals(1, result.duplicateRecordIds.size());
    }
}

这种方案完全不依赖Org内的重复规则配置,测试稳定性最高,也能覆盖所有分支逻辑。

方案2:使用@isTest(SeeAllData=true)依赖预配置规则

如果不想重构现有代码,可以提前在测试环境中创建并激活对应的重复/匹配规则,测试类加@isTest(SeeAllData=true)注解,直接插入两条符合重复条件的记录触发规则即可:

@isTest(SeeAllData=true)
private class DuplicateCheckApiTest {
    @isTest
    static void testDuplicateTrigger() {
        Account acc1 = new Account(Name='重复测试客户', Phone='13800000000');
        insert acc1;

        Account acc2 = new Account(Name='重复测试客户', Phone='13800000000');
        Test.startTest();
        List<DuplicateCheckResult> results = new DuplicateCheckApi().createRecords(new List<Account>{acc2});
        Test.stopTest();

        System.assertEquals(1, results.size());
        System.assertEquals(acc1.Id, results[0].duplicateRecordIds[0]);
    }
}

注意该方案测试依赖环境配置,若Org内的规则被修改或停用,测试会直接失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:27:01