Доступ к значению Trigger.New в тестовом классе Apex - PullRequest
0 голосов
/ 01 марта 2019

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 Ответ

0 голосов
/ 01 марта 2019

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

  • Согласно вашему требованию, У меня есть триггер, который создает новый объект 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; 
    }
    
    }
    
...