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
Jay2Jay2 

Trigger seemingly not acting on test case update

Hi all,

 

This may end up being a dumb question, but I'm very grateful for any help! I have a trigger that I'm trying to test, and though it works when I test it manually via a UI case update, I can't get the test to work at all.

 

The trigger is designed to catch cases before update and, if the associated asset has changed, update a field on the case to match a corresponding field on its asset. Here's a snippet of the test:

 

[test cases and assets created and inserted above, including optedInAsset and caseForOptedOutAsset ...]

Case updatedVersion1 = [Select Id, Opt_In__c, AssetId from Case where Id=:caseForOptedOutAsset.Id limit 1];

updatedVersion1.AssetId = ID.valueOf(optedInAsset.Id);

update updatedVersion1;

updatedVersion1 = [Select Id, Opt_In__c, AssetId from Case where Id=:updatedVersion1.Id limit 1];

System.assertEquals(true, updatedVersion1.Opt_In__c);

[...]

 

For some reason, this assert always fails, though, again, it works smoothly in the UI. I don't seem to even be able to force it--it's like the "before update" trigger is being ignored, and the AssetId field is just being updated without firing any trigger.

 

Is there anything that could cause a trigger to not fire or be somehow truncated in the context of an Apex test?

 

Thanks again!

 

kevoharakevohara

Could you post your code?  Also, are you inserting a new Case record for your test or querying one from the database?  Best practices say you should always insert the records your are going to be testing.  Is it possible that you are querying a record that does not meet your opt-in criteria?

Jay2Jay2

Hi Kevin,

 

Thank you! The trigger I've added this functionality to is a bit of a beast, but I'll scrub it down to the essentials. I am inserting the records that I'm testing, so there's a chance that's the issue, but I'd put in additional asserts to verify that 1) the case's asset was changing to the right one after the update and 2) that asset did meet the criteria that should cause the case field to update.

 

Trigger:

trigger UpdateOptInData on Case (before update) {

	if(Trigger.isUpdate){ // this is repetitive, after I've streamlined this for review
        	// pull in asset info in bulk
        	Map<id, Asset> relatedAssets = getCaseAssetInfo(Trigger.New);

		// bulk-query related asset info
		Set<id> assetIds = new Set<id>();
		for (Case c : caseList) {
			if (c.AssetId != null && !assetIds.contains(c.AssetId)) {
				assetIds.add(c.AssetId);  
			}
		}
		
		// run bulk query
		Map<id, Asset> relatedAssets = new Map<id, Asset>([Select Opt_In__c from Asset where Id in :assetIds]);

                // update Opt_In__c if the associated asset has changed
                if (c.AssetId != Trigger.oldMap.get(c.id).AssetId) {
                	boolean optInValue;
			if (c.AssetId != null) {
        			optInValue = relatedAssets.get(c.AssetId).Opt_In__c;
        		} else {
        	        	optInValue = false;
        		}
			c.Opt_In__c = optInValue;
                }
 	}
}

 

Test:

/**
 * Tests logic around management of the Opt_In__c field on the Case object, which should
 * always match the Opt_In__c field on the associated asset, or be set to false if no
 * asset is associated with a given case.
 */
@isTest
private class optInLogicTest {

  /****** Helper Methods ******/
  static Map<String,String> getMapWithMatchingName(String searchString, List<Map<String,String>> maps) {
    Map<String,String> matchingMap;
    for (Map<String,String> currMap : maps) {
      if (currMap.get('Name') == searchString) {
        matchingMap = currMap;
      }
    }
    return matchingMap;
  }
  
   /****** TEST ACCOUNTS ******/
  
  static List<Map<String,String>> loadTestAccounts() {
    List<Map<String,String>> testAccounts = new List<Map<String,String>>();
    
    Map<String,String> customerAccount;
    customerAccount = new Map<String,String>{'Name' => 'Customer Account',
                             'BillingCountry' => 'US'
                             };
    testAccounts.add(customerAccount);
    
    return insertTestAccounts(testAccounts);
  }
  
  // create each account and load its Id back into its map
  static List<Map<String,String>> insertTestAccounts(List<Map<String,String>> testAccounts) {
    List<Map<String,String>> moddedList = new List<Map<String,String>>();
    for (Map<String,String> accountScheme : testAccounts) {
      Account acct = new Account(Name = accountScheme.get('Name'),
                     BillingCountry = accountScheme.get('BillingCountry'));
      insert acct;
      accountScheme.put('Id', acct.Id);
      moddedList.add(accountScheme);
    }
    return moddedList;
  }
  
  /****** TEST ASSETS ******/
  
  static List<Map<String,String>> loadTestAssets(List<Map<String,String>> testAccounts) {
    List<Map<String,String>> testAssets = new List<Map<String,String>>();
    
    Map<String,String> optedInAsset;
    optedInAsset = new Map<String,String>{'Name' => 'Opted-in Asset',
                           'Opt_In__c' => 'true',
                           'AccountId' => getMapWithMatchingName('Customer Account', testAccounts).get('Id')
                           };
    testAssets.add(optedInAsset);
    
    Map<String,String> optedOutAsset;
    optedOutAsset = new Map<String,String>{'Name' => 'Opted-out Asset',
                           'Opt_In__c' => 'false',
                           'AccountId' => getMapWithMatchingName('Customer Account', testAccounts).get('Id')
                           };
    testAssets.add(optedOutAsset);
    
    return insertTestAssets(testAssets);
  }
  
  // insert each asset and load its Id back into its map
  static List<Map<String,String>> insertTestAssets(List<Map<String,String>> testAssets) {
    List<Map<String,String>> moddedList = new List<Map<String,String>>();
    for (Map<String,String> assetScheme : testAssets) {
      Boolean optIn = (assetScheme.get('Opt_In__c') == 'true') ? true : false;
      Asset asset = new Asset(Name = assetScheme.get('Name'),
      				AccountId = assetScheme.get('AccountId'),
				Opt_In__c = optIn);
      insert asset;
      assetScheme.put('Id', asset.Id);
      moddedList.add(assetScheme);
    }
    return moddedList;
  }
    
    // Run tests
    static testMethod void runAssetChangesTests(){
		// prep test data
		List<Map<String,String>> testAccounts = loadTestAccounts();
		List<Map<String,String>> testAssets = loadTestAssets(testAccounts);

		// test opted-in
		String targetAssetName = 'Opted-in Asset';
		Case caseForOptedInAsset = new Case(AccountId = ID.valueOf(getMapWithMatchingName('Opted-in Asset', testAssets).get('AccountId')),
                      Product__c = 'Google Apps',
                      AssetId = ID.valueOf(getMapWithMatchingName('Opted-in Asset', testAssets).get('Id'))
                      );
		insert caseForOptedInAsset;
		caseForOptedInAsset = [Select Id, Opt_In__c from Case where Id=:caseForOptedInAsset.Id limit 1];
		System.assertEquals(true, caseForOptedInAsset.Opt_In__c);
		
		// switch case asset to opted out asset
		Case updatedVersion1 = [Select Id, Opt_In__c, AssetId from Case where Id=:caseForOptedInAsset.Id limit 1];
		updatedVersion1.AssetId = ID.valueOf(getMapWithMatchingName('Opted-out Asset', testAssets).get('Id'));
		update updatedVersion1;
		updatedVersion1 = [Select Id, Opt_In__c, AssetId from Case where Id=:updatedVersion1.Id limit 1];
		
		System.assertEquals(false, updatedVersion1.Opt_In__c);
    }
}