测试 Shipping Invoice 应用
在将应用程序打包到 AppExchange 之前,75% 的代码必须被单元测试覆盖。本章展示 Shipping Invoice 示例应用的完整测试实现——包括触发器代码、测试类和最佳实践总结。
Calculate 触发器:批量处理模式
Calculate 触发器在 Line Item 插入/更新/删除后自动重新计算 Invoice 的总额。关键技术:使用 Map 收集唯一 Invoice ID(Map 不允许重复键——自动去重)、根据触发器类型设置 subtract 标志(插入/更新=1,删除=-1)、批量 SOQL 查询相关 Invoice 和 Line Item、循环更新每条 Invoice 的总额。遵循批量触发器最佳实践——不使用 Trigger.new[0] 假设单条记录。
trigger calculate on Item__c (after insert, after update, after delete) {
Map<ID, Invoice__c> updateMap = new Map<ID, Invoice__c>();
Integer subtract;
List<Item__c> itemList;
if (trigger.isInsert || trigger.isUpdate) {
itemList = Trigger.new;
subtract = 1;
} else if (trigger.isDelete) {
itemList = Trigger.old;
subtract = -1;
}
for (Item__c item : itemList) {
if (!updateMap.containsKey(item.Invoice__c)) {
updateMap.put(item.Invoice__c, new Invoice__c(Id = item.Invoice__c, Total__c = 0));
}
}
for (Item__c item : [SELECT Id, Cost__c, Invoice__c FROM Item__c
WHERE Invoice__c IN :updateMap.keySet()]) {
Invoice__c inv = updateMap.get(item.Invoice__c);
inv.Total__c += (item.Cost__c * subtract);
}
update updateMap.values();
}
ShippingDiscount 触发器与测试类
ShippingDiscount 触发器:在 Invoice 插入前判断总额是否超过阈值(如 100)——超过则应用运费折扣(设置 ShippingDiscount__c 字段)。示例展示条件业务逻辑在 before insert 中的最佳放置位置——在记录保存前修改值。
Test 类验证以下操作成功完成:
- 插入 Line Items——验证 Invoice 总额正确计算
- 更新 Line Items——验证总额重新计算
- 删除 Line Items——验证总额减去已删除项
- 应用运费折扣——验证 ShippingDiscount 正确设置
- 负向测试——坏输入验证(如 null 成本/负数量)
测试类使用 @isTest 注解——使用 @testSetup 创建共享测试数据(Invoice + Line Items 基础数据)。每个测试方法验证一个特定用例——确保清晰的失败原因。使用 Test.startTest()/stopTest() 控制执行边界和 Governor Limit 重置。
应用架构与最佳实践总结
Shipping Invoice 应用展示的核心模式:
- 触发器处理逻辑分离——触发器只做最小工作(收集 ID → 调用 handler 类方法)。Handler 类包含所有业务逻辑——便于测试和复用
- 批量处理——所有触发器代码设计为处理多条记录。使用 Map/Set 组织数据——减少 SOQL 查询和 DML 语句
- 测试覆盖所有场景——插入/更新/删除 + 正向/负向 + 单条/批量。触发器 + 类 + 测试 = 完整的质量保证
- 使用事务边界——DML 操作在单一事务中——任何步骤失败全部回滚。触发器内的异常阻止操作完成
- Governor Limit 意识——使用 Map 缓存查询结果避免 SOQL 循环。批量 DML(update updateMap.values())vs 逐条 update
恭喜你完成了全部 32 章的 Apex Developer Guide 学习之旅!从入门概念到高级集成和测试,这套完整的知识体系将支持你构建健壮、可扩展、可维护的 Salesforce 应用。