2015-11-30 57 views
0

您好!Salesforce觸發器測試錯誤

我正在爲Salesforce內的觸發器進行單元測試,並且遇到一個我似乎無法解決的錯誤,所以我希望有更多經驗的人可以幫助我重新回到正軌。我在Google上搜尋過很多次,但是我無法找到解決方案。

目的:
我一直負責編寫一個觸發器,它會處理好保持每個開發人員的情況下排名所需的邏輯。每個開發人員都分配了案例,這些案例可能會或可能沒有業務確定的優先級。每位開發人員在任何時候都只能優先處理10個案例。任何其他情況下,排名字段中只會有一個空值。如果插入,更新或刪除了具有排名的個案,則分配給具有排名的該開發者的所有其他個案必須相應地自動更新。任何等級高於10的情況都將被清除。

問題:
我已經完成了觸發和觸發器處理程序類現在我編寫單元測試,以覆蓋所有的單元測試。當我完成我的第一個單元測試方法時,我得到了一個引用工作流問題的錯誤。我發現並糾正了這個問題,但在完成我的第二個單元測試方法後,我再次得到相同的錯誤。我可以將兩種方法和其他方法中的任何一種註釋掉,但是每當我將它們一起運行時,我會得到第一個和第二個失敗,並且會出現相同的原始錯誤。

錯誤:
System.DmlException: Upsert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, A workflow or approval field update caused an error when saving this record. Contact your administrator to resolve it. Developer Assigned Email: invalid email address: false: []

代碼:

Trigger Code -

/*************************************************************************************** 
* @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); 
       } 
      } 
     } 
    } 
} 

Trigger Handler Code -

/*************************************************************************************** 
* @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; 
    } 
} 

Trigger Handler Test Code -

/*************************************************************************************** 
* @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 = '[email protected]', UserName = '[email protected]', 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 = '[email protected]', 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; 
    } 
} 

Workflow Code -I didn't write this one, but click to see pic

CASE(Resource_Assigned__c , 
    "Kimberly REDACTED","[email protected]", 
    "Josh REDACTED","[email protected]", 
    "Robert REDACTED","[email protected]", 
    "Jose REDACTED","[email protected]", 
    "Ryan REDACTED","[email protected]", 
    "Lloyd REDACTED","[email protected]", 
    "Nathan REDACTED","[email protected]", 
    "Amber REDACTED","[email protected]", 
    "Ora REDACTED","[email protected]", 
    "Jason REDACTED","[email protected]", 
    "Shalini REDACTED","[email protected]", 
    "Siva REDACTED","[email protected]", 
    "Quinn REDACTED","[email protected]", 
    "Adrienne REDACTED","[email protected]", 
    "Vasantha REDACTED","[email protected]", 
    "Michael REDACTED","[email protected]", 
    "Sudheera REDACTED","[email protected]", 
    "Test Developer","[email protected]", 
    "false") 

我真的很感激任何幫助,您都可以給我一個!

問候,
邁克爾

+0

歡迎來到Stack Overflow。你的問題包含了大量的代碼。爲了增加獲得答案的機會,我建議儘可能將代碼減少到[MCVE]。 – Matt

回答

0

這裏是我做過什麼來解決我的問題。

我重構了測試並刪除了兩個測試開發人員的創建。相反,我抓住了我們使用的下拉列表中包含的兩個隨機開發人員,然後在測試中使用了這些開發人員。

由於所有設置的方式,我不需要使用生產數據(SeeAllData = true)來完成此修復工作,並且在更改代碼之後,我從來沒有遇到過另一個測試問題。