Salesforce单元测试失败求助:CountCasesOfContact类测试问题排查
Salesforce单元测试失败排查求助
我是Salesforce新手,正在学习单元测试。为CountCasesOfContact类编写的单元测试始终失败,目前连插入事件的测试都无法通过,恳请协助排查问题。以下是我的类代码与单元测试代码:
原CountCasesOfContact类代码
public class CountCasesOfContact { private List<Case> caseList; private List<Case> oldList; public static void countCases(List<Case> caseList, List<Case> oldList){ Map<Id, Contact> contactsToUpdate = new Map<Id, Contact>(); //Run the trigger for all after events, check if object has trigger.new and/or trigger.old and collect parent object and it's id in a map if(Trigger.isAfter && Trigger.new != null){ for(Case cs: caseList) { contactsToUpdate.put(cs.ContactId, new Contact(Id=cs.ContactId,Open_Cases_Count__c=0, Closed_Cases_Count__c = 0)); } } if(Trigger.isAfter && Trigger.old != null) { for(Case cs: oldList) { contactsToUpdate.put(cs.ContactId, new Contact(Id=cs.ContactId,Open_Cases_Count__c=0, Closed_Cases_Count__c = 0)); } } //remove null id-contact pairs from map contactsToUpdate.remove(null); //Get count result of open/closed Cases for each contact and set the value to related fields for(AggregateResult result: [SELECT COUNT(Id) caseCount, ContactId ContactId FROM Case WHERE Status = 'Closed' AND ContactId = :contactsToUpdate.keySet() GROUP BY ContactId] ) { contactsToUpdate.get((Id)result.get('ContactId')).Closed_Cases_Count__c=(Integer)result.get('caseCount'); } for(AggregateResult result: [SELECT COUNT(Id) caseCount, ContactId ContactId FROM Case WHERE Status != 'Closed' AND ContactId = :contactsToUpdate.keySet() GROUP BY ContactId] ) { contactsToUpdate.get((Id)result.get('ContactId')).Open_Cases_Count__c=(Integer)result.get('caseCount'); } update contactsToUpdate.values(); } }
原单元测试代码
@isTest public class CountCasesOfContactTest { @isTest private static void countCasesTestInsert(){ Test.startTest(); Contact ct = new Contact(LastName = 'Test Contact', Open_Cases_Count__c = 0, Closed_Cases_Count__c = 0); insert ct; Case cs = new Case(ContactId = ct.id, Subject = 'Test Case', Status = 'New', Origin = 'Phone'); insert cs; CountCasesOfContact.countCases([Select id From Case], null); Test.stopTest(); Contact cnt = [SELECT id, Open_Cases_Count__c, Closed_Cases_Count__c FROM Contact]; system.assertEquals(1, cnt.Open_Cases_Count__c); system.assertEquals(0, cnt.Closed_Cases_Count__c); } }
问题排查与修正方案
核心问题点
- 依赖Trigger上下文导致逻辑不执行:原类中
Trigger.isAfter在单元测试直接调用方法时为false,导致收集关联ContactId的代码块完全跳过,后续更新逻辑根本无法触发。 - 查询Case时缺少ContactId字段:测试代码中调用方法时传入的
[Select id From Case]未包含ContactId,遍历Case列表时cs.ContactId为null,即使Trigger逻辑生效,也会被contactsToUpdate.remove(null)清空。 - Contact查询无明确条件:测试中查询Contact时未指定Id,若测试环境存在其他Contact数据,会导致查询结果异常。
修正后的类代码
移除对Trigger.isAfter的依赖,让方法专注于处理传入的Case列表关联的Contact:
public class CountCasesOfContact { public static void countCases(List<Case> caseList, List<Case> oldList){ Map<Id, Contact> contactsToUpdate = new Map<Id, Contact>(); // 收集所有非空的关联ContactId if(caseList != null){ for(Case cs: caseList) { if(cs.ContactId != null){ contactsToUpdate.put(cs.ContactId, new Contact(Id=cs.ContactId, Open_Cases_Count__c=0, Closed_Cases_Count__c = 0)); } } } if(oldList != null) { for(Case cs: oldList) { if(cs.ContactId != null){ contactsToUpdate.put(cs.ContactId, new Contact(Id=cs.ContactId, Open_Cases_Count__c=0, Closed_Cases_Count__c = 0)); } } } // 更新Contact的案件计数 for(AggregateResult result: [SELECT COUNT(Id) caseCount, ContactId ContactId FROM Case WHERE Status = 'Closed' AND ContactId = :contactsToUpdate.keySet() GROUP BY ContactId] ) { contactsToUpdate.get((Id)result.get('ContactId')).Closed_Cases_Count__c=(Integer)result.get('caseCount'); } for(AggregateResult result: [SELECT COUNT(Id) caseCount, ContactId ContactId FROM Case WHERE Status != 'Closed' AND ContactId = :contactsToUpdate.keySet() GROUP BY ContactId] ) { contactsToUpdate.get((Id)result.get('ContactId')).Open_Cases_Count__c=(Integer)result.get('caseCount'); } update contactsToUpdate.values(); } }
修正后的测试代码
确保传入包含ContactId的Case列表,且查询Contact时指定明确条件:
@isTest public class CountCasesOfContactTest { @isTest private static void countCasesTestInsert(){ Test.startTest(); Contact ct = new Contact(LastName = 'Test Contact', Open_Cases_Count__c = 0, Closed_Cases_Count__c = 0); insert ct; Case cs = new Case(ContactId = ct.id, Subject = 'Test Case', Status = 'New', Origin = 'Phone'); insert cs; // 传入包含ContactId的Case列表 CountCasesOfContact.countCases([SELECT Id, ContactId FROM Case WHERE Id = :cs.Id], null); Test.stopTest(); // 通过ContactId精准查询,避免数据干扰 Contact cnt = [SELECT Id, Open_Cases_Count__c, Closed_Cases_Count__c FROM Contact WHERE Id = :ct.Id]; System.assertEquals(1, cnt.Open_Cases_Count__c); System.assertEquals(0, cnt.Closed_Cases_Count__c); } }
内容的提问来源于stack exchange,提问作者627
相关产品推荐
相关产品推荐

