tl; dr -如何让测试类等到特定触发器完成更新或插入后再继续测试?
背景
我有一个触发器,每当创建一个Account对象时,它就会创建一个新的Portal_Content__c
对象,然后将两个记录相互关联(请参阅下面的 Account Trigger )。
我还在Portal_Content__c
对象上创建了一个触发器,当删除记录时将触发该触发器。删除后,触发器将查找相关的Account
记录并将其删除(请参见下面的门户内容触发器)。
我的问题与我的门户内容测试类有关(下面的最终代码块)。当我在帐户记录上运行DML插入时,帐户触发器应使用在帐户触发器中创建的门户网站内容记录填充a.Portal_Content_Record__c
字段。但是,当我运行system.debug()
测试时,它表明运行SOQL查询时a.Portal_Content_Record__c
字段为空。通过匹配名称搜索Portal Content记录,我已经能够绕过此问题,但是我想通过按准确的ID搜索来使脚本更加健壮。
问题
在继续进行测试之前,如何使门户内容测试类别等到帐户触发器填充a.Portal_Content_Record__c
字段?
-代码块-
帐户触发器
trigger AccountHandler on Account (before insert, after insert, after update, after delete) {
List<Account> alist = Trigger.New;
List<Account> oldlist = Trigger.Old;
// Create new Portal Content with same name as Account if Account is record type 'College/University,'
// then assign newly created Portal Content to 'Portal Content Record' lookup field on new Account
if(Trigger.isBefore && Trigger.isInsert){
for(Account a : alist) {
if (a.RecordTypeId == '012i0000001Iy1H') {
Portal_Content__c p = new Portal_Content__c(
Name=a.Name,
RecordTypeId='012i0000001J1zZ'
);
insert p;
a.Portal_Content_Record__c = p.Id;
}
}
}
// Delete Portal Content record referenced in an Account's 'Portal Content Record' lookup field
// if the Account is deleted
if (Trigger.isAfter && Trigger.isDelete){
for(Account a : oldlist){
for(Portal_Content__c p : [SELECT ID FROM Portal_Content__c WHERE ID = :a.Portal_Content_Record__c]){
delete p;
}
}
}
// After the new Portal Content record has been created, assign the Account ID of the Account that created it
// to the 'School SFDC ID' field on the new Portal Content record.
if (Trigger.isAfter && Trigger.isInsert){
for(Account a : alist){
List<Portal_Content__c> plist = [SELECT ID FROM Portal_Content__c WHERE Id = :a.Portal_Content_Record__c];
for(Portal_Content__c p : plist){
p.School_SFDC_ID__c = a.Id;
update p;
}
}
}
// Prevent more than one Account from being assigned to a single Portal Content record
if (Trigger.isAfter && Trigger.isUpdate) {
for(Account a : alist){
if (a.Portal_Content_Record__c != null){
List<Account> alist = [SELECT ID FROM Account WHERE Portal_Content_Record__c = :a.Portal_Content_Record__c];
system.debug('alist: ' + alist);
if (alist.size() > 1) {
a.addError('The Portal Content record you selected is already associated with another School. Please select a different Portal Content record');
}
}
}
}
}
门户内容触发器
trigger PortalContentHandler on Portal_Content__c (before insert, after update, after insert, after delete) {
// If Portal Content is deleted and Account is tied to Account record, delete Account record
if(Trigger.isAfter && Trigger.isDelete){
List<Portal_Content__c> plist = Trigger.old;
for(Portal_Content__c p : plist) {
List<Account> alist = [SELECT ID FROM Account WHERE Id = :p.School_SFDC_ID__c];
for(Account a : alist){
delete a;
}
}
}
// If more than one Portal Content with the same name, prevent new Portal Content record from being created
else if(Trigger.isAfter && (Trigger.isUpdate || Trigger.isInsert)){
List<Portal_Content__c> plist = Trigger.New;
for(Portal_Content__c p : plist){
List<Portal_Content__c> pquery = [SELECT ID FROM Portal_Content__c WHERE Name = :p.Name];
if(pquery.size() > 1){
p.addError('There is already a Portal Content record with this name. Please select a different name.');
}
}
}
}
门户内容测试类
@isTest
public class PortalContentHandlerTest {
@isTest static void createThenDeletePortalContent(){
Account a = new Account(Name='deletePortalTest',RecordTypeId='012i0000001Iy1H');
insert a;
List<Portal_Content__c> plist = [SELECT ID FROM Portal_Content__c WHERE Name = :a.Name];//Id = :a.Portal_Content_Record__c];
system.debug('Delete Info: a.Id = ' + a.Id + ', Portal_Content_Record = ' + a.Portal_Content_Record__c+ ', plist = ' + plist);
for(Portal_Content__c p : plist){
delete p;
}
system.debug('Delete Info: a.Id = ' + a.Id);
List<Account> checklist = [SELECT ID FROM Account WHERE Id = :a.Id];
system.debug(checklist);
system.assertEquals(0, checklist.size());
}
答案 0 :(得分:0)
我已经在组织中对其进行了测试。请在下面找到我的评论。
根据您的要求,我有一个触发器,无论何时创建一个Account对象,该触发器都会创建一个新的Portal_Content__c对象,然后将两个记录彼此关联(请参见下面的Account Trigger)。
我发现Account(Portal_Content_Record__c )
和Portal Content (School_SFDC_ID__c)
之间存在关系。您正在设置Portal_Content_Record__c
。但您也需要链接School_SFDC_ID__c
才能满足您的要求。请找到以下代码
trigger AccountHandler on Account (before insert, after insert, after update, after delete) {
List<Account> alist = Trigger.New;
List<Account> oldlist = Trigger.Old;
// Create the new Portal Content with the same name as Account if Account is record type College/University,
// then assign newly created Portal Content to Portal Content Record lookup field on new Account
if(Trigger.isBefore && Trigger.isInsert){
for(Account a : alist) {
if (a.RecordTypeId == '012i0000001Iy1H') {
Portal_Content__c p = new Portal_Content__c(
Name=a.Name,
RecordTypeId='012i0000001J1zZ',
School_SFDC_ID__c = a.id
);
insert p;
a.Portal_Content_Record__c = p.Id;
}
}
}
}
我看到的唯一问题是delete
没有被覆盖
PortalContentHandler
,因为它不符合以下条件
List<Account> alist = [SELECT ID FROM Account WHERE Id =
:p.School_SFDC_ID__c];
在创建时进行填充
上面所述的门户内容。
此外,由于没有要查询的Portal Content数据,因此您需要更改测试类。在测试类中,您只能获取在那里创建的数据。由AccountHandler创建的那个不会成为您的测试类的一部分。创建与触发器中创建的数据相同的数据。
@isTest
public class PortalContentHandlerTest {
@isTest static void createThenDeletePortalContent(){
Account a = new
Account(Name='deletePortalTest',RecordTypeId__c='012i0000001Iy1H');
insert a;
Portal_Content__c p = new Portal_Content__c(
Name=a.Name,
RecordTypeId__c='012i0000001J1zZ',
School_SFDC_ID__c = a.id
);
insert p;
delete p;
}
}