使用 AggregateResults 函数为 Salesforce 自定义控制器编写单元测试
Writing unit test for Salesforce custom controller using AggregateResults function
资深 SFDC 管理员,第一次深入 APEX。
我为仪表板组件(visualforce 页面)构建了一个自定义控制器。控制器可以工作,但需要单元测试才能推送到生产环境(不要问 - 组织覆盖率低)。
这是控制器:
public with sharing class retrieveMRR {
public Summary[] Summaries { get; set; }
public retrieveMRR() {
AggregateResult[] results =
[SELECT SUM(Opportunity.MRR_Projected_EOM__c) MRRtm,
SUM(Opportunity.Billing_MRR_Last_Month__c) MRRlm,
SUM(Opportunity.Billing_MRR_M_minus2__c) MRRlm2,
SUM(Opportunity.Billing_MRR_Last_Month_Pilot_Change__c) chgPlusPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_Pilot_Change2__c) chgMinusPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_NPilot_Change__c) chgPlusNPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_NPilot_Change2__c) chgMinusNPilotlm FROM Opportunity ];
Summaries = new List<Summary>();
for (AggregateResult ar : results) {
Summaries.add(new Summary(ar));
}
}
public class Summary {
public Decimal MRRtm { get; private set; }
public Decimal MRRlm { get; private set; }
public Decimal MRRlm2 { get; private set; }
public Decimal chgPlusPilotlm { get; private set; }
public Decimal chgMinusPilotlm { get; private set; }
public Decimal chgPlusNPilotlm { get; private set; }
public Decimal chgMinusNPilotlm { get; private set; }
public Summary(AggregateResult ar) {
MRRtm = (Decimal) ar.get('MRRtm');
MRRlm = (Decimal) ar.get('MRRlm');
MRRlm2 = (Decimal) ar.get('MRRlm2');
chgPlusPilotlm = (Decimal) ar.get('chgPlusPilotlm');
chgMinusPilotlm = (Decimal) ar.get('chgMinusPilotlm');
chgPlusNPilotlm = (Decimal) ar.get('chgPlusNPilotlm');
chgMinusNPilotlm = (Decimal) ar.get('chgMinusNPilotlm');
}
}
}
如果需要,这里是 Visualforce 页面
<apex:page controller="retrieveMRR">
<apex:pageBlock title="MRR">
<apex:pageBlockSection columns="3" >
<apex:repeat value="{!Summaries}" var="summary">
<apex:outputText style="font-weight:800; font-size:16px" value="Month"></apex:outputText>
<apex:outputText style="font-weight:800; font-size:16px" value="Value"></apex:outputText>
<apex:outputText style="font-weight:800; font-size:16px" value="+ New / - Lost"></apex:outputText>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (actual)"><apex:param value="{!TODAY()-60}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm2}" /></apex:outputText> </apex:outputLink>
<apex:outputText value=""></apex:outputText>
<apex:outputText style="font-style:italic" value=" change"><apex:param value="{!TODAY()}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm-summary.MRRlm2}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-weight:400 ; align: center" value="Pilot"> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.chgPlusPilotlm+summary.chgMinusPilotlm}" /></apex:outputText></apex:outputLink>
<apex:outputLink target="_parent" value=""><apex:outputText value="+{0, number, $###,###,##0}/{1, number, $###,###,##0}">
<apex:param value="{!summary.chgPlusPilotlm}" />
<apex:param value="{!summary.chgMinusPilotlm}" /> </apex:outputText></apex:outputLink>
<apex:outputText style="font-weight:400 ; align: center" value="Non-Pilot"> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.chgPlusNPilotlm+summary.chgMinusNPilotlm}" /></apex:outputText></apex:outputLink>
<apex:outputLink target="_parent" value=""><apex:outputText value="+{0, number, $###,###,##0}/{1, number, $###,###,##0}">
<apex:param value="{!summary.chgPlusNPilotlm}" />
<apex:param value="{!summary.chgMinusNPilotlm}" /> </apex:outputText></apex:outputLink>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (actual)"><apex:param value="{!TODAY()-31}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-style:italic" value="change"></apex:outputText>
<apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRtm-summary.MRRlm}" /></apex:outputText>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (projected)"><apex:param value="{!TODAY()}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRtm}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
我已经为其他 APEX 控制器完成了单元测试,但我不知道如何测试只是一个聚合函数的控制器。帮助将不胜感激!
使用测试 class 作为数据工厂(参见 trailhead HERE)来创建帐户和该帐户的机会(例如 createTestAccount 和 createTestOpportunity class)。
然后在测试 class 中创建控制器实例 class 并做一些断言(参见 HERE 的一个很好的例子)
我做了很多谷歌搜索和灵魂搜索来解决这个问题。
我一直在寻找的解决方案是权宜之计:我不在此 class 中写入数据。我不需要数据工厂和疯狂的设备来测试它。真的很难把这些例子应用到一个简单的 class 中,它只查询数据库然后打印值。
因此,我编写的测试很简单并且符合我的目的(满足代码覆盖率限制):
@isTest
public class badtest {
static testMethod void runTest() {
retrieveMRR a = new retrieveMRR();
}
}
我只是创建了一个 class,然后实例化了我试图测试的 class。 BAM 100% 代码覆盖率。
希望这对学习 APEX 的人有所帮助,以便为仪表板构建 Visualforce 页面。
资深 SFDC 管理员,第一次深入 APEX。
我为仪表板组件(visualforce 页面)构建了一个自定义控制器。控制器可以工作,但需要单元测试才能推送到生产环境(不要问 - 组织覆盖率低)。
这是控制器:
public with sharing class retrieveMRR {
public Summary[] Summaries { get; set; }
public retrieveMRR() {
AggregateResult[] results =
[SELECT SUM(Opportunity.MRR_Projected_EOM__c) MRRtm,
SUM(Opportunity.Billing_MRR_Last_Month__c) MRRlm,
SUM(Opportunity.Billing_MRR_M_minus2__c) MRRlm2,
SUM(Opportunity.Billing_MRR_Last_Month_Pilot_Change__c) chgPlusPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_Pilot_Change2__c) chgMinusPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_NPilot_Change__c) chgPlusNPilotlm ,
SUM(Opportunity.Billing_MRR_Last_Month_NPilot_Change2__c) chgMinusNPilotlm FROM Opportunity ];
Summaries = new List<Summary>();
for (AggregateResult ar : results) {
Summaries.add(new Summary(ar));
}
}
public class Summary {
public Decimal MRRtm { get; private set; }
public Decimal MRRlm { get; private set; }
public Decimal MRRlm2 { get; private set; }
public Decimal chgPlusPilotlm { get; private set; }
public Decimal chgMinusPilotlm { get; private set; }
public Decimal chgPlusNPilotlm { get; private set; }
public Decimal chgMinusNPilotlm { get; private set; }
public Summary(AggregateResult ar) {
MRRtm = (Decimal) ar.get('MRRtm');
MRRlm = (Decimal) ar.get('MRRlm');
MRRlm2 = (Decimal) ar.get('MRRlm2');
chgPlusPilotlm = (Decimal) ar.get('chgPlusPilotlm');
chgMinusPilotlm = (Decimal) ar.get('chgMinusPilotlm');
chgPlusNPilotlm = (Decimal) ar.get('chgPlusNPilotlm');
chgMinusNPilotlm = (Decimal) ar.get('chgMinusNPilotlm');
}
}
}
如果需要,这里是 Visualforce 页面
<apex:page controller="retrieveMRR">
<apex:pageBlock title="MRR">
<apex:pageBlockSection columns="3" >
<apex:repeat value="{!Summaries}" var="summary">
<apex:outputText style="font-weight:800; font-size:16px" value="Month"></apex:outputText>
<apex:outputText style="font-weight:800; font-size:16px" value="Value"></apex:outputText>
<apex:outputText style="font-weight:800; font-size:16px" value="+ New / - Lost"></apex:outputText>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (actual)"><apex:param value="{!TODAY()-60}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm2}" /></apex:outputText> </apex:outputLink>
<apex:outputText value=""></apex:outputText>
<apex:outputText style="font-style:italic" value=" change"><apex:param value="{!TODAY()}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm-summary.MRRlm2}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-weight:400 ; align: center" value="Pilot"> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.chgPlusPilotlm+summary.chgMinusPilotlm}" /></apex:outputText></apex:outputLink>
<apex:outputLink target="_parent" value=""><apex:outputText value="+{0, number, $###,###,##0}/{1, number, $###,###,##0}">
<apex:param value="{!summary.chgPlusPilotlm}" />
<apex:param value="{!summary.chgMinusPilotlm}" /> </apex:outputText></apex:outputLink>
<apex:outputText style="font-weight:400 ; align: center" value="Non-Pilot"> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.chgPlusNPilotlm+summary.chgMinusNPilotlm}" /></apex:outputText></apex:outputLink>
<apex:outputLink target="_parent" value=""><apex:outputText value="+{0, number, $###,###,##0}/{1, number, $###,###,##0}">
<apex:param value="{!summary.chgPlusNPilotlm}" />
<apex:param value="{!summary.chgMinusNPilotlm}" /> </apex:outputText></apex:outputLink>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (actual)"><apex:param value="{!TODAY()-31}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRlm}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-style:italic" value="change"></apex:outputText>
<apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRtm-summary.MRRlm}" /></apex:outputText>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
<apex:outputText style="font-weight:800" value="{0,date,MMMM YYYY} (projected)"><apex:param value="{!TODAY()}" /> </apex:outputText>
<apex:outputLink target="_parent" value=""><apex:outputText value="{0, number, currency}"><apex:param value="{!summary.MRRtm}" /></apex:outputText> </apex:outputLink>
<apex:outputText value="{0, number, currency}"><apex:param value="{!null}" /></apex:outputText>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
我已经为其他 APEX 控制器完成了单元测试,但我不知道如何测试只是一个聚合函数的控制器。帮助将不胜感激!
使用测试 class 作为数据工厂(参见 trailhead HERE)来创建帐户和该帐户的机会(例如 createTestAccount 和 createTestOpportunity class)。
然后在测试 class 中创建控制器实例 class 并做一些断言(参见 HERE 的一个很好的例子)
我做了很多谷歌搜索和灵魂搜索来解决这个问题。
我一直在寻找的解决方案是权宜之计:我不在此 class 中写入数据。我不需要数据工厂和疯狂的设备来测试它。真的很难把这些例子应用到一个简单的 class 中,它只查询数据库然后打印值。
因此,我编写的测试很简单并且符合我的目的(满足代码覆盖率限制):
@isTest
public class badtest {
static testMethod void runTest() {
retrieveMRR a = new retrieveMRR();
}
}
我只是创建了一个 class,然后实例化了我试图测试的 class。 BAM 100% 代码覆盖率。
希望这对学习 APEX 的人有所帮助,以便为仪表板构建 Visualforce 页面。