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
FuguSailorFuguSailor 

Test code issue

I'm writing some test code to cover someone else's code and I'm having an issue where the code checks the values in a reference class. The code has a Case class with some custom fields and one of these fields is a reference to a master Case object. I build both case objects, assign the Id of the master object to the child and in the test method, the values all look good. The problem is that when the code gets into the production code, the reference fields are not getting resolved. I do an upsert of all of the instances in the test code before calling the code to be tested.

 

I've come to understand that there is blocking of selecting live data in test code so I'm wondering if that is what is causing the reference fields to not be resolved.

 

This makes it so that the best I can get on code coverage is 66% and would like to get much better but because many of the required values are null, a good share of the code does not get executed.

 

Thanks in advance for your help.

Best Answer chosen by Admin (Salesforce Developers) 
FuguSailorFuguSailor

Found the problem. I was setting a field that I shouldn't have and when I commented the line, things all of a sudden started to work.

 

 

Sorry for the bother but thanks for the help.

All Answers

sfdcfoxsfdcfox
You have to create a mockup of every record that will be referenced by code in your test. For example, if you're testing a case trigger that uses accounts, you have to create a test account, then a test case.
FuguSailorFuguSailor

But I am. They have a Case object that references a master Case object. I firts instanciate the master object, filling in all of the information, then upsert it. Then I build the child object and set the reference field to reference the master object and upsert the child. When the code runs, the values that are in the master object do not get resolved. I checked the values in the master in the test method and they are all there and valid. When the live code is executed, the values for the master object are all null. I checked the Id of the master object in the test method and the reference Id in the live code and they match but the reference data is all null.

sfdcfoxsfdcfox
There shouldn't be an ID that you can "compare to"; you should be creating all of your data from scratch. All reference fields must have their records created within the test method.
FuguSailorFuguSailor

But I am creating all of the instances in the test code. The problem is that when the production code runs, the values for the referenced class aren't resolved. If you attempt to fill in the references in the test code, you get a run time exception about dereferencing an object.

 

So let's say we do something like the following:

public class clz{
  public void foo(){
    Map<Id, Case> caseMap = new Map<Id, Case><[ SELECT Id, Master_Case__r.Custom_Field1__c, Master_Case__r.Custom_Field2__c FROM Case WHERE Master_Case__r.Custom_Field1__c = 'some value' AND Master_Case__r.Custom_Field2__c = 'another value']);

// a bunch of code
  }

  static testMetod void testFoo(){
    Case master = new Case( Custom_Field1__c = 'some value', Custom_Field2__c = 'another value' );
    upsert master;
    Case c = new Case();
    upsert c; c.Master_Case__c = master.Id; Test.StartTest(); clz z = new clz(); z.foo(); Test.StopTest(); } }

 The problem is that in foo() the values for the master case instance are not resolved and are all null in foo().

sfdcfoxsfdcfox
There's your problem. You assigned Master_Case__c after you upserted case C. Since it wasn't committed to the database, the query wouldn't see it. Swap the two lines, and it should work.
FuguSailorFuguSailor

Actually, the sample is wrong but the real code is correct. The sample is not the real code. It was just a sample of what I was trying to do. So if you will, pretend the master reference is before the upsert and tell me why the references' fields are not being resolved later.

sfdcfoxsfdcfox

Well, in that case, it should work. Here's a functional example that I wrote:

 

public class TestRelationships {
    void foo() {
        Contact[] contacts = [SELECT Id,AccountId,Account.Name FROM Contact];
        Map<Id,Account> accounts = new Map<Id,Account>([SELECT Id,Name FROM Account]);
        for(Contact contactRecord:contacts) {
            System.assertEquals(accounts.get(contactRecord.AccountId).Name,contactRecord.Account.name);
        }
    }
    
    @isTest
    static void test() {
        Account a = new Account(name='test');
        insert a;
        Contact c = new Contact(AccountId=a.Id,firstname='test',lastname='test');
        insert c;
        TestRelationships tr = new TestRelationships();
        tr.foo();
        
    }
}

Your problem isn't with the code/code sample you've posted, but obviously somewhere else; this code is a sample proof that the system works correctly. Perhaps you should take a look closer to the problem.

FuguSailorFuguSailor

Hmm.

 

I put debug log lines in the test function and in the live code trying to figure out what is the problem. I'm assuming that the live code works(someone else's work) and I was just adding test coverage for the deployment. The debug lines showed the values were good while in the test function but in the live code, the reference Id was the same but none of the referenced object's data was resolved. Like the sample, both the master and child instances were created in the test function and upserted before calling the class's functions. I'll play with it a little more and see what happens.

FuguSailorFuguSailor

Found the problem. I was setting a field that I shouldn't have and when I commented the line, things all of a sudden started to work.

 

 

Sorry for the bother but thanks for the help.

This was selected as the best answer