当前位置: 首页 > 知识库问答 >
问题:

Salesforce触发器测试错误

爱花蜂
2023-03-14

你好

我正在Salesforce内部为trigger进行单元测试,我不断遇到一个似乎无法解决的错误,所以我希望有更多经验的人能帮助我回到正轨。我已经在Google上搜索过很多次了,我的代码结构也被弄乱了,但我找不到解决方案。

目的:
我的任务是编写一个触发器,该触发器将处理维护每个开发人员的案例排名所需的逻辑。每个开发人员都被分配了案例,这些案例可能有也可能没有由业务确定的优先级。每个开发人员在任何时候只能优先考虑10个案例。任何其他案例在排名字段中都只有空值。如果插入、更新或删除了具有排名的案例,那么分配给该开发人员的所有其他案例都必须相应地自动更新。任何排名高于10的案例都将被取消。

问题:
我已经完成了触发器和触发器处理程序类,现在我正在编写单元测试来覆盖所有单元测试。当我完成第一个单元测试方法时,出现了一个引用工作流问题的错误。我发现并纠正了这个问题,但在我完成了第二个单元测试方法之后,我又出现了同样的错误。我可以注释掉这两个方法中的任何一个,也可以注释掉其他过程,但每当我将它们一起运行时,第一个过程会通过,第二个过程会失败,并出现相同的原始错误。

错误:
系统。DmlException:更新失败。第0行的第一个异常;第一个错误:CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY,工作流或审批字段更新在保存此记录时导致错误。联系您的管理员解决它。开发人员分配的电子邮件:无效的电子邮件地址:假:[]

代码:

触发代码-

/***************************************************************************************
* @author:      Michael *REDACTED*
* @email:        michael.*REDACTED*@*REDACTED*.com
* @date:         11/09/15
* @brief:         This is a trigger for the Case object that will modify the rank of the Cases
*                     assigned to the developer based on a priority set by the Administrator.
***************************************************************************************/
trigger CaseRankTrigger on Case (before insert, before update, before delete) {
    // trigger level variables
    private static Boolean firstRun = true;
    private RecordType ticketRecordType = [SELECT Id FROM RecordType WHERE SobjectType = 'Case' AND Name = 'Salesforce Service Ticket' LIMIT 1];
    private List<Case> newTrigger = trigger.new;
    private List<Case> currentTrigger = trigger.old;
    private List<Case> qualifiedNewCases = new List<Case>();
    private List<Case> qualifiedCurrentCases = new List<Case>();
     // makes sure that the trigger only runs once
    if (firstRun) {
        firstRun = false;
        // populate trigger Case lists
        qualifyCases();
        if (qualifiedNewCases.size() == 1 || qualifiedCurrentCases.size() == 1) {
            // the CaseRankTriggerHandler constructor method takes (List<Case>, List<Case>, String)
            if (trigger.isInsert) CaseRankTriggerHandler handler = new CaseRankTriggerHandler(qualifiedNewCases, qualifiedCurrentCases, 'Insert'); // if a new Case is being inserted into the database
            if (trigger.isUpdate) CaseRankTriggerHandler handler = new CaseRankTriggerHandler(qualifiedNewCases, qualifiedCurrentCases, 'Update'); // if an existing Case is being updated
            if (trigger.isDelete) CaseRankTriggerHandler handler = new CaseRankTriggerHandler(qualifiedNewCases, qualifiedCurrentCases, 'Delete'); // if an existing Case is deleted from the database
        }
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/24/15
    * @brief:       The qualifyCases method populates a list of Cases for each trigger
    *                   that are of the Salesforce Service Ticket record type only.
    * @return:     Void
    ***************************************************************************************/
    public void qualifyCases() {
        if (newTrigger != null ) {
            for (Case c : newTrigger) {
                if (c.recordTypeId == ticketRecordType.Id) {
                    qualifiedNewCases.add(c);
                }
            }
        }
        if (currentTrigger != null) {
            for (Case c : currentTrigger) {
                if (c.recordTypeId == ticketRecordType.Id) {
                    qualifiedCurrentCases.add(c);
                }
            }
        }
    }
}

触发器处理程序代码-

/***************************************************************************************
* @author:      Michael *REDACTED*
* @email:        michael.*REDACTED*@*REDACTED*.com
* @date:         11/09/15
* @brief:         This is a Case object trigger handler class that provides logic to the CaseRankTrigger for manipulating
*                     the ranks of all Cases assigned to a developer based on a priority that is set by an Administrator.
***************************************************************************************/
public with sharing class CaseRankTriggerHandler {
    // class level variables
    private static Boolean firstRun = true;
    private static Boolean modify = false;
    private static Integer MAX = 10;
    private static Integer MIN = 1;
    private List<Case> newTrigger {get; set;}
    private List<Case> currentTrigger {get; set;}
    private List<Case> cases {get; set;}
    private List<Case> newList {get; set;}
    private List<Case> currentList {get; set;}
    private String developer {get; set;}
    private Decimal newRank {get; set;}
    private Decimal currentRank {get; set;}
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       Class constructor method.
    * @return:     Void
    ***************************************************************************************/
    public CaseRankTriggerHandler(List<Case> newT, List<Case> oldT, String type) {
        if (firstRun) { // makes sure that the trigger only runs once
            firstRun = false;
            InitializeTrigger(newT, oldT, type); // initializes the trigger
            if (developer != null) { // skips trigger if DML is performed on a Case with no developer assigned
                ModificationCheck(type); // determines if Cases need to be modified
                if (modify) ModificationLogic(type); // modifies Cases if needed
            }
        }
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       The InitializeTrigger method initializes the handler class based on the type of trigger fired.
    * @return:     Void
    ***************************************************************************************/
    private void InitializeTrigger(List<Case> newT, List<Case> oldT, String type) {
        if (type == 'Insert') {
            this.newTrigger = newT;
            this.developer = newTrigger[0].Resource_Assigned__c;
            this.newRank = newTrigger[0].Case_Rank__c;
            this.newList = [SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Resource_Assigned__c = :developer AND Case_Rank__c != null AND Case_Rank__c = :newRank ORDER BY Case_Rank__c];
        } else if (type == 'Update') {
            this.newTrigger = newT;
            this.currentTrigger = oldT;
            this.developer = newTrigger[0].Resource_Assigned__c;
            this.newRank = newTrigger[0].Case_Rank__c;
            this.currentRank = currentTrigger[0].Case_Rank__c;
            this.newList = [SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Resource_Assigned__c = :developer AND Case_Rank__c != null AND Case_Rank__c = :newRank ORDER BY Case_Rank__c];
            this.currentList = [SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Resource_Assigned__c = :developer AND Case_Rank__c != null AND Case_Rank__c = :currentRank ORDER BY Case_Rank__c];
        } else if (type == 'Delete') {
            this.currentTrigger = oldT;
            this.developer = currentTrigger[0].Resource_Assigned__c;
            this.currentRank = currentTrigger[0].Case_Rank__c;
        }
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       The ModificationCheck method ensures various conditions are met, depending on the type
    *                   of trigger that was fired, before modifying the ranks of the Cases assigned to the developer.
    * @return:     Void
    ***************************************************************************************/
    private void ModificationCheck(String type) {
        if (type == 'Insert') {
            // the Case being inserted has a new rank not equal to null and if the assigned developer already has a Case with the
            // same rank as the new rank, we will proceed to modification, if not the record will be inserted without modification.
            if (newRank != null && !newList.isEmpty()) {
                modify = true;
            }
        } else if (type == 'Update') {
            // if the Case being updated has ranks with different values in both triggers we will proceed to the next check, if not the record is updated without modification.
            if (newRank != currentRank) {
                // if the Case being updated has a (new rank equal to null and a current rank not equal to 10) or
                // if the Case being updated has a new rank not equal to null, we will proceed to the next check,
                // if not the record is updated without modification.
                if ((newRank == null && currentRank != 10) || newRank != null) {
                    // if the assigned developer on the Case being updated already has a Case with the same rank as the new or current rank, we will proceed to modification,
                    // if not the record is updated without modification.
                    if (!newList.isEmpty() || !currentList.isEmpty()) {
                        modify = true;
                    }
                }
            }
        } else if (type == 'Delete') {
            // if the Case being deleted has current rank not equal to null, we will proceed to modification, if not the record is deleted without modification.
            if (currentRank != null) {
                modify = true;
            }
        }
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       If a Case rank needs to be updated the ModificationLogic method calls the appropriate
    *                   computation method based on trigger type and the values of newRank and currentRank.
    * @return:     Void
    ***************************************************************************************/
    private void ModificationLogic(String type) {
        if (type == 'Insert') {
            for (Case c : newTrigger) {
                // calls the IncreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank greater than or equal to the new rank.
                IncreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :newTrigger AND Resource_Assigned__c = :developer AND Case_Rank__c >= :newRank ORDER BY Case_Rank__c]);
            }
        } else if (type == 'Update') {
            for (Case c : newTrigger) {
                if (currentRank == null) {
                    // if the current rank is null - calls the IncreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank greater than or equal to the new rank.
                    IncreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :newTrigger AND Resource_Assigned__c = :developer AND Case_Rank__c >= :newRank ORDER BY Case_Rank__c]);
                } else if (newRank == null) {
                    // if the new rank is null - calls the DecreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank greater than the current rank.
                    DecreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :newTrigger AND Resource_Assigned__c = :developer AND Case_Rank__c > :currentRank ORDER BY Case_Rank__c]);
                } else if (newRank > currentRank) {
                    // if the new rank is greater than the current rank - calls the DecreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank less than or equal to the new rank and greater than to the current rank.
                    DecreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :newTrigger AND Resource_Assigned__c = :developer AND (Case_Rank__c <= :newRank AND Case_Rank__c > :currentRank) ORDER BY Case_Rank__c]);
                } else if (newRank < currentRank) {
                    // if the new rank is less than the current rank - calls the IncreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank a.
                    IncreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :newTrigger AND Resource_Assigned__c = :developer AND (Case_Rank__c >= :newRank AND Case_Rank__c < :currentRank) ORDER BY Case_Rank__c]);
                }
            }
        } else if (type == 'Delete') {
            for (Case c : currentTrigger) {
                // calls the DecreaseCaseRank method and passes it a list of Cases that are assigned to the developer that have a rank greater than the current rank.
                DecreaseCaseRank([SELECT Subject, CaseNumber, Case_Rank__c FROM Case WHERE Id NOT IN :currentTrigger AND Resource_Assigned__c = :developer AND Case_Rank__c > :currentRank ORDER BY Case_Rank__c]);
            }
        }
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       The DecreaseCaseRank method provides the logic required to properly
    *                   decrease or null out the ranks of the Cases assigned the the developer.
    * @return:     Void
    ***************************************************************************************/
    private void DecreaseCaseRank(List<Case> cases) {
        // if the list of Cases passed in by the ModificationLogic method isn't empty then it will iterate through the
        // list and decrease their ranks by 1 or null out the rank if it is not within the acceptable limits (1-10).
        if (!cases.isEmpty()) {
            for (Case c : cases) {
                if (c.Case_Rank__c >= 1 && c.Case_Rank__c <= 10) {
                    c.Case_Rank__c = c.Case_Rank__c - 1;
                } else {
                    c.Case_Rank__c = null;
                }
            }
            update cases;
        }
        return;
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/16/15
    * @brief:       The IncreaseCaseRank method provides the logic required to properly
    *                   increase or null out the ranks of the Cases assigned the the developer.
    * @return:     Void
    ***************************************************************************************/
    private void IncreaseCaseRank(List<Case> cases) {
        // if the list of Cases passed in by the ModificationLogic method isn't empty then it will iterate through the
        // list and increase their ranks by 1 or null out the rank if it is not within the acceptable limits (1-10).
        if (!cases.isEmpty()) {
            for (Case c : cases) {
                if (c.Case_Rank__c >= 1 && c.Case_Rank__c < 10) {
                    c.Case_Rank__c = c.Case_Rank__c + 1;
                } else {
                    c.Case_Rank__c = null;
                }
            }
            update cases;
        }
        return;
    }
}

触发器处理程序测试代码-

/***************************************************************************************
* @author:      Michael *REDACTED*
* @email:        michael.*REDACTED*@*REDACTED*.com
* @date:         11/24/15
* @brief:         This is the test class for the CaseRankTriggerHandler class
***************************************************************************************/
@isTest
public with sharing class CaseRankTriggerHandlerTest {
    // class level variables
    static User testRequestor = createTestRequestor();
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/24/15
    * @brief:       The InsertCase_NewRankNull test method ensures that the insert functionality of the
    *                   CaseRankTrigger is working as intended when a new Case is inserted with a null rank.
    ***************************************************************************************/
    @isTest
    static void InsertCase_NewRankNull() {
        // creates the initial case load for 'Test Developer' by passing in a list of integers that will become the ranks for the cases
        createDeveloperCase_Multiple(new List<Integer> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
        // starting the test by inserting a new Case with a null rank
        Test.startTest();
        createDeveloperCase_Single('Null', null);
        Test.stopTest();
        // queries the system to create a map of Cases assigned to 'Test Developer' that are keyed by Rank with Subject as the value
        Map<Decimal, String> caseMap = createCaseMap();
        // system asserts to ensure that Cases are in the proper order
        System.assertEquals('Test Case (1)', caseMap.get(1), 'Test Developer should have \'Test Case (1)\' as rank 1 but instead has ' + caseMap.get(1));
        System.assertEquals('Test Case (2)', caseMap.get(2), 'Test Developer should have \'Test Case (2)\' as rank 2 but instead has ' + caseMap.get(2));
        System.assertEquals('Test Case (3)', caseMap.get(3), 'Test Developer should have \'Test Case (3)\' as rank 3 but instead has ' + caseMap.get(3));
        System.assertEquals('Test Case (4)', caseMap.get(4), 'Test Developer should have \'Test Case (4)\' as rank 4 but instead has ' + caseMap.get(4));
        System.assertEquals('Test Case (5)', caseMap.get(5), 'Test Developer should have \'Test Case (5)\' as rank 5 but instead has ' + caseMap.get(5));
        System.assertEquals('Test Case (6)', caseMap.get(6), 'Test Developer should have \'Test Case (6)\' as rank 6 but instead has ' + caseMap.get(6));
        System.assertEquals('Test Case (7)', caseMap.get(7), 'Test Developer should have \'Test Case (7)\' as rank 7 but instead has ' + caseMap.get(7));
        System.assertEquals('Test Case (8)', caseMap.get(8), 'Test Developer should have \'Test Case (8)\' as rank 8 but instead has ' + caseMap.get(8));
        System.assertEquals('Test Case (9)', caseMap.get(9), 'Test Developer should have \'Test Case (9)\' as rank 9 but instead has ' + caseMap.get(9));
        System.assertEquals('Test Case (10)', caseMap.get(10), 'Test Developer should have \'Test Case (10)\' as rank 10 but instead has ' + caseMap.get(10));
        System.assertEquals('Test Case (Null)', caseMap.get(null), 'Test Developer should have \'Test Case (Null)\' as rank null but instead has ' + caseMap.get(null));
        delete [SELECT Id FROM Case WHERE Resource_Assigned__c = 'Test Developer'];
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/24/15
    * @brief:       The InsertCase_NewRankNotNull test method ensures that the insert functionality of the
    *                   CaseRankTrigger is working as intended when a new Case is inserted with a rank that is not null.
    ***************************************************************************************/
    @isTest
    static void InsertCase_NewRankNotNull() {
        // creates the initial case load for 'Test Developer' by passing in a list of integers that will become the ranks for the cases
        createDeveloperCase_Multiple(new List<Integer> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
        // starting the test by inserting a new Case with a null rank
        Test.startTest();
        createDeveloperCase_Single('NewNotNull', 4);
        Test.stopTest();
        // queries the system to create a map of Cases assigned to 'Test Developer' that are keyed by Rank with Subject as the value
        Map<Decimal, String> caseMap = createCaseMap();
        // system asserts to ensure that Cases are in the proper order
        System.assertEquals('Test Case (1)', caseMap.get(1), 'Test Developer should have \'Test Case (1)\' as rank 1 but instead has ' + caseMap.get(1));
        System.assertEquals('Test Case (2)', caseMap.get(2), 'Test Developer should have \'Test Case (2)\' as rank 2 but instead has ' + caseMap.get(2));
        System.assertEquals('Test Case (3)', caseMap.get(3), 'Test Developer should have \'Test Case (3)\' as rank 3 but instead has ' + caseMap.get(3));
        System.assertEquals('Test Case (NewNotNull)', caseMap.get(4), 'Test Developer should have \'Test Case (NewNotNull)\' as rank 4 but instead has ' + caseMap.get(4));
        System.assertEquals('Test Case (4)', caseMap.get(5), 'Test Developer should have \'Test Case (4)\' as rank 5 but instead has ' + caseMap.get(5));
        System.assertEquals('Test Case (5)', caseMap.get(6), 'Test Developer should have \'Test Case (5)\' as rank 6 but instead has ' + caseMap.get(6));
        System.assertEquals('Test Case (6)', caseMap.get(7), 'Test Developer should have \'Test Case (6)\' as rank 7 but instead has ' + caseMap.get(7));
        System.assertEquals('Test Case (7)', caseMap.get(8), 'Test Developer should have \'Test Case (7)\' as rank 8 but instead has ' + caseMap.get(8));
        System.assertEquals('Test Case (8)', caseMap.get(9), 'Test Developer should have \'Test Case (8)\' as rank 9 but instead has ' + caseMap.get(9));
        System.assertEquals('Test Case (9)', caseMap.get(10), 'Test Developer should have \'Test Case (9)\' as rank 10 but instead has ' + caseMap.get(10));
        System.assertEquals('Test Case (10)', caseMap.get(null), 'Test Developer should have \'Test Case (10)\' as rank null but instead has ' + caseMap.get(null));
        delete [SELECT Id FROM Case WHERE Resource_Assigned__c = 'Test Developer'];
    }
    /***************************************************************************************
    * @author:    Michael *REDACTED*
    * @email:      michael.*REDACTED*@*REDACTED*.com
    * @date:       11/24/15
    * @brief:       The createCaseMap method queries all the developers Cases then creates a map
    *                   keyed by Rank with the Subject as the value. This map will be used to ensure that
    *                   the Cases are in the proper order after any DML has been performed on a Case.
    * @return:    Map<Decimal, String>
    ***************************************************************************************/
    static Map<Decimal, String> createCaseMap() {
        List<Case> caseList = [SELECT Case_Rank__c, Subject FROM Case WHERE Resource_Assigned__c = 'Test Developer' ORDER BY Case_Rank__c];
        Map<Decimal, String> caseMap = new Map<Decimal, String>();
        for (Case c : caseList) {
            caseMap.put(c.Case_Rank__c, c.Subject);
        }
        return caseMap;
    }
    /***************************************************************************************
    * TEST DATA SECTION - Refactor out of test class after creating Test Data Factory
    ***************************************************************************************/
    static User createTestRequestor() {
        Profile testProfile = [SELECT Id from Profile where Name = 'Standard User'];
        User requestor = new User(FirstName = 'Test', LastName = 'Requestor', Alias = 'Test.Req', Email = 'newtestrequestor@null.com', UserName = 'newtestrequestor@null.com', ProfileId = testProfile.Id,
                                  TimeZoneSidKey = 'America/Los_Angeles', LocaleSidKey = 'en_US', EmailEncodingKey = 'UTF-8', LanguageLocaleKey = 'en_US');
        insert requestor;
        return requestor;
    }
    static List<Case> createDeveloperCase_Multiple(List<Integer> ranks) {
        List<Case> developerCaseLoad = new List<Case>();
        Case developerCase;
        Integer count = 0;
        for (Integer rank : ranks) {
            count++;
            developerCase = new Case(Subject = 'Test Case (' + count + ')', Service_Request_Type__c = 'Development', Requestor__c = testRequestor.Id, Description = 'Foo', Business_Value_of_Change__c = 'Bar',
                                     Business_Area__c = 'Warranty', Requested_Implementation_Date__c = Date.today(), Resource_Assigned__c = 'Test Developer', Resource_Assigned_Email__c = 'newtestdeveloper@null.com', Case_Rank__c = rank);
            developerCaseLoad.add(developerCase);
        }
        for (Case c : developerCaseLoad) {
        }
        upsert developerCaseLoad;
        return developerCaseLoad;
    }
    static Case createDeveloperCase_Single(String name, Integer rank) {
        Case developerCase = new Case(Subject = 'Test Case (' + name + ')', Service_Request_Type__c = 'Development', Requestor__c = testRequestor.Id, Description = 'Foo', Business_Value_of_Change__c = 'Bar',
                                      Business_Area__c = 'Warranty', Requested_Implementation_Date__c = Date.today(), Resource_Assigned__c = 'Test Developer', Case_Rank__c = rank);
        upsert developerCase;
        return developerCase;
    }
}

工作流代码-这不是我写的,但单击查看图片

CASE( Resource_Assigned__c ,
     "Kimberly REDACTED","foo@bar.com",
     "Josh REDACTED","foo@bar.com",
     "Robert REDACTED","foo@bar.com",
     "Jose REDACTED","foo@bar.com",
     "Ryan REDACTED","foo@bar.com",
     "Lloyd REDACTED","foo@bar.com",
     "Nathan REDACTED","foo@bar.com",
     "Amber REDACTED","foo@bar.com",
     "Ora REDACTED","foo@bar.com",
     "Jason REDACTED","foo@bar.com",
     "Shalini REDACTED","foo@bar.com",
     "Siva REDACTED","foo@bar.com",
     "Quinn REDACTED","foo@bar.com",
     "Adrienne REDACTED","foo@bar.com",
     "Vasantha REDACTED","foo@bar.com",
     "Michael REDACTED","foo@bar.com",
     "Sudheera REDACTED","foo@bar.com",
     "Test Developer","newtestdeveloper@null.com",
     "false")

我真的很感谢你们在这件事上能给我的任何帮助<向迈克尔问好

共有1个答案

游乐池
2023-03-14

这是我所做的来解决我的问题。

我重构了测试并删除了两个测试开发人员的创建。相反,我抓取了我们使用的下拉列表中包含的两个随机开发人员,然后在测试中使用了这些开发人员。

由于一切都是这样设置的,我不需要使用生产数据(SeeAllData=true)来进行修复,在更改代码后,我再也没有遇到过测试问题。

 类似资料:
  • 下面是我的顶点触发器。我是一名初学者,正在尝试编写其测试类,但不断出现错误“System.DmlException:Insert失败。第0行出现第一个异常;第一个错误:REQUIRED\u FIELD\u MISSING,错误:只有在产品相关列表上为此opportunity选择了价格手册,才能选择产品。:[]”。 在Opportunity上触发TrgrOptyHighestCustmorePric

  • 大家好, 我正在尝试为我帮助编写的触发器编写一个测试类。触发器使用名为trigger\u help\u c的字段,该字段是通过添加opportunity Type和Account ID派生的公式字段,如果在过去90天内已在该帐户上创建了该类型的opportunity,则在插入之前激发。除非配置文件是系统管理员。这是我的触发器: 我在写测试课时遇到了困难,我像往常一样不知所措。我写了以下内容,但我不

  • 我已在Salesforce APEX中记录了触发器。它工作正常。 触发器代码为: 现在我正在尝试为它的测试类编写代码。它在线上给出错误,说对象无法解析为字符串。 测试等级代码为: 期待找到解决方案。任何帮助都将不胜感激。 谢谢

  • 我已经为此发疯了。我的IF循环中没有任何东西通过我的测试类触发,我不知道为什么。我在网上阅读了很多,看起来我做的事情是正确的,但它仍然没有解决我的代码覆盖率。这是运行的最后一行:如果(isIn==True){ 之后我无法让任何东西在IF循环中运行,我已经颠倒了逻辑,它仍然无法运行。我觉得当有人指出它时,我会踢自己,但这是我的代码: } 这是我的测试类:

  • 我在Apex中有一个触发器。如何编写检查触发器是否被调用的单元测试?

  • 问题内容: 假设我有一个类似 测试此bean实际上将在其指定日期( 即 最接近每月15日的工作日)触发的最佳方法是什么? 更新 :这应该是一个单元测试,所以我不会启动虚拟机或更改系统时间。 问题答案: 首先,没有必要进行自我测试。它是spring框架的一部分,已经过测试。 更好的测试可能是测试您的cron表达式是否符合您的期望。这里的一种选择是使用Quartz的类。给定一个对象,您可以调用,该表达