Sunday, January 18, 2015

Curious Case of Disappearing ID

Problem

Last week, I was deploying some changes to the recently deployed Apex classes into the production, but somehow it was failing on previously migrated test classes that were not related to the changes being deployed. To confirm that it had something to do with production environment, rather than the new code, I ran those pre-existing test classes in the production environment, and they were indeed failing even without the changes (I also had them run in Sandbox and confirm that they passed).  My initial suspicion was that someone had added something like a validation rule on the sObjects for which I was generating test data.  Although it was related to the test records being generated, the problem, it turned out, was not related to the validation rule, but something rather more strange.

The test classes had a structure similar to the following where I had a static method to generate test data for all the test methods and a test method that queries for the test data.
@isTest private class TestCustomController {   static void createBackground() {     List<Account> testAccts = new List<Account> {       new Account(Name = 'Test Account 1'),       new Account(Name = 'Test Account 2')};     Database.insert(testAccts);
    List<Account_Child__c> children = new List<Account_Child__c> {       new Account_Child__c(Name = 'Child 1', Account__c = testAccts[0].id)};    Database.insert(children);   }
  static testMethod void manipulateCustomController() {     TestCustomController.createBackground();
    Account queriedAcct = [SELECT Id FROM Account WHERE Name = 'Test Account 1'];
    // Initialize custom controller, pass on the account ID,     //and call method to query for the children of the accounts.   } }
To debug the problem in the production, I had put breakpoints in the createBackground() method after the insertion of the account and in the manipulateCustomController() method after query for the account through Developer Console and ran this test class.  What I found out was that the ID of the Test Account 1 in the createBackground() didn't match the ID in the manipulateCustomController()!

Workaround

I tried moving the code in the createBackground() method into the manipulateCustomController() method, and that did resulted in the ID being consistent through out the run of that test method.  However, this did not completely solve the test failure as I had another weird issue where the symbol table not showing some properties of an in-memory instance of a sObject, while it showed in the heap.

Takeaway

This does demonstrate that there are major differences in the internal implementation of the Test and "Production" environments of the Salesforce, mainly that the Test environment is somewhat unstable and has weird kink in it.  Also, it does demonstrate how valuable breakpoints can be when debugging problem in the Production org. 

No comments:

Post a Comment