Доступ к значению Trigger.New в тестовом классе Apex

tl; dr - Как заставить тестовый класс подождать, пока не будет выполнен определенный триггер с его обновлениями или вставками, прежде чем продолжить тест?

Фон

У меня есть триггер, который создает новый Portal_Content__c объект каждый раз, когда создается объект Account, а затем связывает обе записи друг с другом (см. Trigger Account ниже).

Я также создал триггер на Portal_Content__c объект, который срабатывает при удалении записи. При удалении триггер ищет соответствующие Account запишите и удалите его (см. раздел "Триггер содержимого портала" ниже).

Мой вопрос касается моего класса тестирования содержания портала (окончательный блок кода ниже). Когда я запускаю вставку DML для записи учетной записи, триггер учетной записи должен заполнить a.Portal_Content_Record__c поле с записью содержимого портала, созданной в триггере учетной записи. Тем не менее, когда я побежал мой system.debug() тесты показали, что a.Portal_Content_Record__c поле является пустым при выполнении запроса SOQL. Мне удалось обойти это, выполнив поиск записи контента портала по совпадению по названию, но я хотел бы сделать скрипт более надежным, выполнив поиск по точному идентификатору.

Вопрос

Как заставить класс тестирования контента портала подождать, пока триггер учетной записи не заполнит 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());
    }

1 ответ

Я проверил это в моей организации. Пожалуйста, найдите мои комментарии ниже.

  • Согласно вашему требованию, у меня есть триггер, который создает новый объект Portal_Content__c при каждом создании объекта Account, а затем связывает обе записи друг с другом (см. Ниже Trigger Account).
    Я вижу, что есть отношения на 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]; Заполните его при создании Контента портала, как описано выше.

  • Кроме того, вам нужно изменить свой тестовый класс, поскольку нет данных для контента портала, который вы пытаетесь запросить. В тестовом классе вы получаете только те данные, которые вы там создали. Тот, который создается 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; 
    }
    
    }
    
Другие вопросы по тегам