Apex Test Class第二个assertEquals断言执行失败问题
Apex测试类assertEquals断言执行失败
问题描述
- 测试目的:验证配置了
isBefore && isInsert或isUpdate触发时机的Trigger逻辑 - 报错现象:代码末尾用于比对SOQL查询返回结果的第二个
assertEquals语句执行失败,对应聚合SOQL查询返回空结果 - 现有操作:测试方法中仅执行基础数据插入操作,无法定位报错根因,完整测试代码如下:
@isTest private class Test_Triggers{ static testMethod void Test_Triggers() { Account acc = new Account(); acc.Name = 'sacasac'; insert acc; Account contateste0 = new Account(); contateste0.Name = 'GRANITOS E MARMORES MACHADO LTDA EPP'; contateste0.Phone = '(27)3727-2929'; insert contateste0; Contact contatoTeste = new Contact(); contatoTeste.FirstName = 'TITANIUM'; contatoTeste.LastName = 'TITANIUM'; contatoTeste.Phone = '3329-4053'; contatoTeste.MobilePhone = '27999970208'; contatoTeste.Email = 'gmmcontabil@gmail.com'; contatoTeste.AccountId = contateste0.Id; insert contatoTeste; Case novoCaso = new Case(); novoCaso.Subject = 'assunto'; novoCaso.Description = 'obs'; novoCaso.AccountId = contateste0.Id; novoCaso.ContactId = contatoTeste.Id; novoCaso.Origin = 'Portal'; insert novoCaso; Opportunity novaOpp = new Opportunity(); novaOpp.AccountId = contateste0.Id; novaOpp.Amount = 4200; novaOpp.Name = '4200'; novaOpp.StageName = 'Pré_Oportunidade'; novaOpp.CloseDate = Date.today(); insert novaOpp; Id idMeta = Schema.SObjectType.Meta__c.getRecordTypeInfosByName().get('CORE').getRecordTypeId(); Id idMeta2 = Schema.SObjectType.Meta__c.getRecordTypeInfosByName().get('NOVO').getRecordTypeId(); Meta__c meta01 = new Meta__c(); meta01.Data__c = Date.today(); meta01.Id_Usuario__c = UserInfo.getUserId(); meta01.Id_Conta__c = contateste0.Id; meta01.RecordTypeId = idMeta; meta01.Valor__c = 53161; insert meta01; System.assertEquals(53161, meta01.Valor__c); Ordem_de_venda__c ordem = new Ordem_de_venda__c(); ordem.Oportunidade__c = novaOpp.Id; ordem.Conta_Principal__c = acc.Id; ordem.Pagador__c = acc.Id; ordem.Data_de_vencimento__c = System.today().addDays(2); ordem.Id_Meta__c = meta01.Id; ordem.Tipo__c = 'Serviço'; insert ordem; List<AggregateResult> aggregateOrdensVenda = [SELECT Id_Meta__c, sum(Valor_faturado__c) total, sum(VlrFor__c) forecast FROM Ordem_de_venda__c WHERE Id_Meta__c =:meta01.Id GROUP BY Id_Meta__c]; // 此处断言失败,SOQL返回空结果 system.assertEquals(1,aggregateOrdensVenda.size()); } }
根因分析
报错核心原因是Salesforce SOQL聚合查询的固有逻辑:当某一分组下所有参与聚合计算的字段值均为null时,该分组不会被包含在返回结果中。
查看插入Ordem_de_venda__c记录的代码,仅给Oportunidade__c、Conta_Principal__c等字段赋值,完全没有给聚合查询用到的Valor_faturado__c、VlrFor__c两个字段赋值,这两个字段默认值为null,导致对应分组不返回,查询结果size为0,断言失败。
除此之外还有两种小概率诱因:
Ordem_de_venda__c对象的isInsert触发器/校验规则/Flow逻辑在入库时清空了Id_Meta__c字段值,导致查询条件匹配不到记录- 触发器逻辑存在异常,导致销售单记录未正常入库
修复方案
- 若业务逻辑要求销售单入库时
Valor_faturado__c、VlrFor__c必须有值,直接在测试类构造测试数据时给两个字段赋值即可:
Ordem_de_venda__c ordem = new Ordem_de_venda__c(); ordem.Oportunidade__c = novaOpp.Id; ordem.Conta_Principal__c = acc.Id; ordem.Pagador__c = acc.Id; ordem.Data_de_vencimento__c = System.today().addDays(2); ordem.Id_Meta__c = meta01.Id; ordem.Tipo__c = 'Serviço'; // 补充聚合字段赋值 ordem.Valor_faturado__c = 1000; ordem.VlrFor__c = 2000; insert ordem;
- 若业务逻辑允许两个字段为null,不要直接用聚合结果判断记录存在,先做普通查询校验数据入库状态,再执行聚合逻辑校验:
// 先验证销售单记录正常插入、关联关系正确 List<Ordem_de_venda__c> existOrdems = [SELECT Id, Id_Meta__c FROM Ordem_de_venda__c WHERE Id_Meta__c = :meta01.Id]; System.assertEquals(1, existOrdems.size(), '关联Meta的销售单未正常插入'); // 再执行聚合查询校验计算逻辑 List<AggregateResult> aggregateOrdensVenda = [SELECT Id_Meta__c, sum(Valor_faturado__c) total, sum(VlrFor__c) forecast FROM Ordem_de_venda__c WHERE Id_Meta__c =:meta01.Id GROUP BY Id_Meta__c];
- 若上述调整后仍报错,排查
Ordem_de_venda__c上的自动化逻辑,确认isInsert时机没有修改Id_Meta__c值、没有拦截记录入库的逻辑。
注:代码中定义的
idMeta2变量未被使用,属于冗余代码,不影响运行但可清理。
内容的提问来源于stack exchange,提问作者Leonardo Oliveira
相关产品推荐
相关产品推荐

