如何通过Apex代码为Apex测试类创建或控制Duplicate/Matching规则
解决方案
首先明确:Apex 原生不支持通过 DML 直接创建/激活/停用重复规则(DuplicateRule)和匹配规则(MatchingRule),这两类属于元数据对象,仅能通过元数据接口操作,而测试上下文内元数据变更不会即时生效,因此你最初提出的两个需求没有可落地的原生实现路径。
以下是两种可实现全量测试覆盖率的可行方案:
方案1:依赖注入+逻辑拆分(最推荐,无环境依赖)
将重复结果处理逻辑从DML调用部分抽离为独立的可测方法,测试时直接手动构造Datacloud.DuplicateResult对象传入即可,不需要真实触发重复规则:
- 重构业务代码,拆分核心逻辑:
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; } }
- 测试类直接构造测试数据覆盖核心逻辑:
@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
相关产品推荐
相关产品推荐

