function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Odd unit test behavior

I'm writing a trigger on a custom object that when the Estimate Approved checkbox is true, it creates an opportunity. I decided to compare the trigger.old and values in order to detect the change. The trigger works great when testing through the UI, but the unit test is consistently failing and I can't figure out why.


Both and trigger.old are passed into a method in a class. Since the method handles other things irrelevant to this issue, I'll only be posting the relevant code:


public static void afterUpdateTrigger (List<SVMXC__Service_Order__c> wos, Map<ID, SVMXC__Service_Order__c> oldWOs){
        Set<ID> woIDs = new Set<ID>();
        for(SVMXC__Service_Order__c wo : wos) {

//queried separately in order to get lookup field values
List<SVMXC__Service_Order__c> workOrders = [SELECT Id, SVMXC__Order_Type__c, RecordType.Name, SVMXC__Service_Contract__r.Territory__c, Dash_1__c, Requirement_Numbers__c, Lines_Created__c, SVMXC__Component__c, Milestone__r.Project__c, SVMXC__Order_Status__c, Estimate_Approved__c, Technician_completed_WO_Date_Time__c, Department__c, SVMXC__Company__c, Location__c, Location__r.Sales_Tax_Schedule__c, Location__r.Name, SVMXC__Problem_Description__c
                                                    FROM SVMXC__Service_Order__c
                                                    WHERE Id IN :woIDs];

List<Opportunity> optysToCreate = new List<Opportunity>();

for(SVMXC__Service_Order__c wo : workOrders) {
            SVMXC__Service_Order__c oldWO = oldWOs.get(wo.Id);
            system.debug('Old Estimate Approved: ' + oldWO.Estimate_Approved__c);
            system.debug('New Estimate Approved: ' + wo.Estimate_Approved__c);


} else if(oldWO.Estimate_Approved__c == false && wo.Estimate_Approved__c == true) {
                 Map<String, Sales_Tax__c> taxMap = Sales_Tax__c.getAll();
                 String schedule = String.valueOf(wo.Location__r.Sales_Tax_Schedule__c);
                 Datetime nowDate =;
                 Date closeDate = date.valueOf(nowDate).addDays(7);
                 String today = nowDate.format('MM-dd-yyyy', 'PST');
                 Opportunity opty = new Opportunity();
                     opty.Name = wo.Location__r.Name + ' Estimate ' + today;
                     opty.CloseDate = closeDate;
                     opty.AccountId = wo.SVMXC__Company__c;
                     opty.Location__c = wo.Location__c;
                     opty.Product_Family__c = 'Service';
                     opty.Company__c = wo.Department__c;
                     opty.Work_Order__c = wo.Id;
                     opty.StageName = 'Budget Quote';
                     opty.Probability = 25;
                     opty.Drop_Ship__c = 'No';
                     opty.LeadSource = 'Technician';
                     opty.Project_Scope__c = wo.SVMXC__Problem_Description__c;
                     if(schedule != null) {
                         opty.Tax_Rate__c = taxMap.get(schedule).Tax_Rate__c;
                     } else {
                         opty.Tax_Rate__c = 0;

try {
              system.debug('Size of Opty List: ' + optysToCreate.size());
              if(!optysToCreate.isEmpty()) {
                  insert optysToCreate;
          } catch (Exception e) {

And here is the unit test. I originally wrote this to be bulkified, but that made the debug log generated from the test run to hit the maximum size allowed and thus cut off the parts I needed to see so I have it only testing one record. Once I figure out what is causing the error it will be bulkified. SeeAllData is also set to true because inserting a SVMXC__Service_Order__c record always fails due to a trigger in a managed package, so instead I query an existing work order and then clone it for testing.


private class workOrderTrigger_UT {
    static testMethod void OptyTest() {
        Account a = new Account (Name ='Account',
                                        BillingCity='PQR ',
                                        BillingState = 'XYZ',
        insert a;
        Contact c = new Contact(FirstName='Brianna',
                                AccountId = a.Id);
        insert c;
        SVMXC__Site__c loc = new SVMXC__Site__c (Name='Location',
                                               SVMXC__Account__c = a.Id,
                                               SVMXC__City__c='PQR ',
                                               SVMXC__State__c = 'XYZ',
                                               Sales_Tax_Schedule__c = 'CALC OC'
        insert loc;
        SVMXC__Service_Order__c wo = [SELECT Id, SVMXC__Contact__c, SVMXC__Order_Type__c, SVMXC__Order_Status__c, Estimate_Approved__c
                                      FROM SVMXC__Service_Order__c
                                      WHERE RecordType.Name = 'Service' AND SVMXC__Order_Status__c = 'Estimate' 
                                      LIMIT 1];
        system.assert(wo != null);
        SVMXC__Service_Order__c woClone = wo.clone(false, true);
                woClone.SVMXC__Company__c = a.Id;
                woClone.Location__c = loc.Id;
                woClone.Department__c = 'MEC';
                woClone.SVMXC__Contact__c = c.Id;
        insert woClone;

system.debug('Old Estimate Approved - Unit Test' + woClone.Estimate_Approved__c); woClone.Estimate_Approved__c = true; update woClone; system.debug('New Estimate Approved - Unit Test' + woClone.Estimate_Approved__c); test.stopTest();
Opportunity opty = [SELECT Id, Work_Order__c FROM Opportunity WHERE Work_Order__c = :woClone.Id]; system.assert(opty != null); } }

The most baffling part is in the debug logs - the debug statements in the trigger say false for both the old record and the new record - as if the update never happened. But the debug statement in the unit test returns true for the new value. When testing the trigger with test records through the UI, those debug logs do show the old value as false and the new value as true.


Here are snippets from the debug logs as well:


Unit Test Debug Log:

13:13:49.314 (30314626000)|SYSTEM_METHOD_ENTRY|[44]|System.debug(ANY)
13:13:49.314 (30314636000)|USER_DEBUG|[44]|DEBUG|Old Estimate Approved - Unit Testfalse
13:13:49.314 (30314642000)|SYSTEM_METHOD_EXIT|[44]|System.debug(ANY)
13:13:49.314 (30314726000)|DML_BEGIN|[46]|Op:Update|Type:SVMXC__Service_Order__c|Rows:1
13:13:49.306 (30306278000)|SYSTEM_METHOD_ENTRY|[119]|System.debug(ANY)
13:13:49.306 (30306291000)|USER_DEBUG|[119]|DEBUG|Old Estimate Approved: false
13:13:49.306 (30306298000)|SYSTEM_METHOD_EXIT|[119]|System.debug(ANY)
13:13:49.306 (30306310000)|SYSTEM_METHOD_ENTRY|[120]|String.valueOf(Object)
13:13:49.306 (30306324000)|SYSTEM_METHOD_EXIT|[120]|String.valueOf(Object)
13:13:49.306 (30306334000)|SYSTEM_METHOD_ENTRY|[120]|System.debug(ANY)
13:13:49.306 (30306341000)|USER_DEBUG|[120]|DEBUG|New Estimate Approved: false
13:13:49.306 (30306346000)|SYSTEM_METHOD_EXIT|[120]|System.debug(ANY)
13:13:49.306 (30306782000)|SYSTEM_METHOD_ENTRY|[333]|System.debug(ANY)
13:13:49.306 (30306791000)|USER_DEBUG|[333]|DEBUG|Size of Opty List: 0
13:13:49.306 (30306797000)|SYSTEM_METHOD_EXIT|[333]|System.debug(ANY)
13:13:49.983 (30983973000)|SYSTEM_METHOD_ENTRY|[47]|System.debug(ANY)
13:13:49.983 (30983985000)|USER_DEBUG|[47]|DEBUG|New Estimate Approved - Unit Testtrue
13:13:49.983 (30983992000)|SYSTEM_METHOD_EXIT|[47]|System.debug(ANY)


UI Debug Log

13:27:08.291 (5291747000)|USER_DEBUG|[119]|DEBUG|Old Estimate Approved: false
13:27:08.291 (5291785000)|USER_DEBUG|[120]|DEBUG|New Estimate Approved: true
13:27:08.297 (5297238000)|SYSTEM_CONSTRUCTOR_ENTRY|[255]|<init>()
13:27:08.297 (5297264000)|SYSTEM_CONSTRUCTOR_EXIT|[255]|<init>()
13:27:08.297 (5297401000)|USER_DEBUG|[333]|DEBUG|Size of Opty List: 1
13:27:08.297 (5297504000)|DML_BEGIN|[335]|Op:Insert|Type:Opportunity|Rows:1

I have no idea what I'm doing wrong here. If there's something I'm missing please point it out. I've been going crazy trying to figure it out on my own!