Salesforce Invocable方法测试传参异常致代码覆盖率不足问题
Salesforce Apex Invocable方法测试覆盖率不足问题修复
问题背景
- 客户升级Salesforce环境后重构了自动化流程对应的Apex代码,生产环境下代码由Flow触发调用时参数传递正常、功能无报错
- 测试环节代码覆盖率仅46%,无法满足生产部署要求
- 日志排查定位:测试运行时
getDonorInfo方法接收到的donationParameters参数为空 - 涉及代码共三类:测试类、Invocable入口类、被调用的业务类(业务类不影响本次问题定位)
现有代码与现象
原有测试类代码
@isTest(SeeAllData = true) public class TestMethods { private static testMethod void doTest() { Test.startTest(); List<ProcessHandlerShowAccounts.DonationParameters> params = new List<ProcessHandlerShowAccounts.DonationParameters>(); ProcessHandlerShowAccounts.getDonorInfo(params); Test.stopTest(); } }
Invocable入口类代码
public class ProcessHandlerShowAccounts { public class DonationParameters { @InvocableVariable(required=true) public String account_id; @InvocableVariable(required=true) public String donation_id; @InvocableVariable(required=true) public String contact_id; } @InvocableMethod(label='getDonorInfo' description='I hope this will work' category='AccountCategory') public static void getDonorInfo(DonationParameters[] donationParameters) { Account[] accounts = new Account[]{}; system.debug('right before we call class ' + donationParameters); ID jobID = System.enqueueJob(new NewDonorLetter2(donationParameters)); } }
异常现象
方法debug日志输出显示入参为空列表:
13:42:34:005 USER_DEBUG [13]|DEBUG|right before we call class: ()
已尝试给@InvocableVariable修饰的变量设置默认值,问题仍未解决:
@InvocableVariable(required=true) public String account_id = "000000000"; @InvocableVariable(required=true) public String donation_id = "000000000"; @InvocableVariable(required=true) public String contact_id = "000000000";
根因分析
- 测试类仅初始化了
DonationParameters类型的空列表,未实例化任何参数对象加入列表,传入方法的本身就是长度为0的空集合,因此debug输出为空,后续业务逻辑也无法正常执行 - 给内部类属性设置默认值不生效的原因是:根本没有创建
DonationParameters类的实例,不存在属性初始化的环节 - 额外问题:测试类使用了
SeeAllData = true配置,不符合Salesforce测试最佳实践,存在依赖生产环境数据导致测试不稳定的风险;若未正确等待异步作业执行,也会导致队列作业部分的代码无法被统计覆盖率
修复方案
- 测试类中移除
SeeAllData = true配置,自行构造测试所需的Account、Contact、捐赠Opportunity等测试数据 - 实例化
DonationParameters参数对象,给对应属性赋值后加入参数列表,再传入getDonorInfo方法,禁止传空列表 - 保留
Test.startTest()和Test.stopTest()结构,Test.stopTest()会强制所有入队的异步Queueable作业同步执行,保证异步逻辑的代码行能被正常统计覆盖率 - 测试末尾增加业务结果断言,验证逻辑执行符合预期
修正后的测试类参考代码
@isTest public class TestMethods { private static testMethod void doTest() { // 构造测试所需基础数据 Account testAcc = new Account(Name = 'Test Donor Account'); insert testAcc; Contact testCon = new Contact(LastName = 'Test Donor', AccountId = testAcc.Id); insert testCon; Opportunity testDonation = new Opportunity( Name = 'Test Donation Record', AccountId = testAcc.Id, Amount = 200, CloseDate = Date.today(), StageName = 'Closed Won' ); insert testDonation; Test.startTest(); // 构造Invocable方法入参 List<ProcessHandlerShowAccounts.DonationParameters> params = new List<ProcessHandlerShowAccounts.DonationParameters>(); ProcessHandlerShowAccounts.DonationParameters singleParam = new ProcessHandlerShowAccounts.DonationParameters(); singleParam.account_id = testAcc.Id; singleParam.donation_id = testDonation.Id; singleParam.contact_id = testCon.Id; params.add(singleParam); // 调用目标方法 ProcessHandlerShowAccounts.getDonorInfo(params); Test.stopTest(); // 此处会强制等待异步作业执行完成,统计对应覆盖率 // 增加断言验证业务结果,例如验证捐赠信记录是否生成、字段值是否符合预期 } }
内容的提问来源于stack exchange,提问作者Trout
相关产品推荐
相关产品推荐

