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
Shital SonkusaleShital Sonkusale 

Formula fields not evaluating in test class

I am trying to cover a method which uses formula field.
This is my test class code:

SObject1__C coltype = new SObject1__C();
coltype.name = 'Name-3312';
insert coltype;
System.debug('--->SObject1.Name = '+coltype.name); // Gives 'Name-3312';

SObject2__C colObj = new SObject2__C();
colObj.SObject1__C = coltype.Id;
insert colObj;  

SObject3__C newCollP = new SObject3__C();
newCollP.SObject2__C = colObj.Id,
insert newCollP;

SObject3__C has a fomula field named 'Col_Type__C' which is evaluated as follows:
"SObject2__r.SObject1__r.Name"
System.debug('--->newCollP.Col_Type__C = '+ newCollP.Col_Type__C); //returns a2Hg0000001tqQ2

This 'Col_Type__C' field's value is then used in a method in a helper class which i am trying to cover. As posted by many, I have tried to query the object SObject3__C and populate the field Col_Type__C in the test class as below. But it's not populatting the formula field's value as 'Name-3312'. 
newCollP = [SELECT Id,SObject2__r.SObject1__r.Name, Col_Type__C from SObject3__C where Id=:newCollP.id];

When I debug Col_Type__C value in helper class it returns some ID. I need the value of  as name of SObject1__C.

What is missing in my code? How can I get the formula field populated? 

Any help is appreciated!
Best Answer chosen by Shital Sonkusale
Shital SonkusaleShital Sonkusale
Hi all,
We have got the issue. SObject1 is a managed package object. Whenever we create SObject1, the managed package code changed it's name to created record's Id. However the change takes some time to reflect when created in a test class. That's why after inserting SObject1,when I queried it's name through soql it returned name as 'Name-3312'. But when using the formula field on sobject3, the name was already replaced by Id of sobject1 and hence it the formula field returned ID ,not the name. The managed package code wasn't caught in debug logs ,so took a long time to figure out whatsw happening.

Thank you all for your help, I am closing this thread now.

All Answers

Glyn Anderson 3Glyn Anderson 3
What happens if you query:
newCollP = [SELECT Id,SObject2__r.SObject1__r.Name, Col_Type__C from SObject3__C where Col_Type__C='Name-3312'];

It might have to do with the two levels of lookup.  Can you create a Col_Type__C formula field on SObject2__C, which is "SObject1__r.Name", and then redefine SObject3__C.Col_Type__C to be "SObject2__r.Col_Type__C"?
Shital SonkusaleShital Sonkusale
Hi Glyn,

When I execute this query in Query editor I get below result:
Id=a33g0000000gAAQ
SObject2__r.SObject1__r.Name = [object Object]
Col_Type__C = 'Real Estate - 3123'

Such results I get.
And I cannot actually change any of the objects. I just need to cover these fields in my test class.
 
Prince_sfdcPrince_sfdc
Tried the same scenario and I think you should query the field once record (having formula field) is inserted. Here's the below example: 
here Account_Name__c is the formula field on OpportunityLineItem (3rd Sobject) 
@isTest
public Class OptyLineItem_Test{
     private static testMethod void testMethod1(){
        
		Id pricebookId = Test.getStandardPricebookId();
		
		//Insert product
        Product2 prod = new Product2();
        prod.name = 'TestProduct';
        prod.IsActive = true;
        insert prod;
        
		//PricebookEntry
		PricebookEntry pbe = new PricebookEntry();
		pbe.Product2Id = prod.Id;
		pbe.pricebook2Id= pricebookId;
		pbe.UnitPrice = 10;
		pbe.IsActive = true;
		insert pbe;
		
        //Insert Account
        Account acc = new Account();
        acc.name = 'TestAccount';
        insert acc;
        
        //Opportunity
        Opportunity opty = new Opportunity();
        opty.Name = 'TestOpty01';
        opty.AccountId = acc.Id;
		opty.StageName = 'Prospect';
		opty.CloseDate = System.today();
        insert opty;
        
        //optyLineItem
        OpportunityLineItem oli = new OpportunityLineItem();
        oli.pricebookEntryId = pbe.Id;
        oli.OpportunityId = opty.Id;
		oli.Quantity = 10;
		oli.TotalPrice =200;
        insert oli;
		
		opportunitylineitem ooli = [Select Account_Name__c from opportunitylineitem where id =: oli.id ];
        System.debug('accName: '+acc.Name+ 'AccountNameFormulaOnOLI : '+ooli.Account_Name__c);
        //System.assertEquals(acc.name, ooli.Account_Name__c);
    }
}

You should get the desired result. Please mark this as best answer if it resolves.
Shital SonkusaleShital Sonkusale
Hi Prince_sfdc,

I tried , but it's still populating some id in Formula field and not the  coltype.name = 'Name-3312'
Prince_sfdcPrince_sfdc
Hi Shital, Is that resolved?
Shital SonkusaleShital Sonkusale
Hi Prince_sfdc , sorry for removing that best answer tag. I am still facing the issue. The answer you provided worked with another object with only 2 level hierarchy i.e parent-child. But the issue still persists for the above mentioned objects. 

I  have tried things like clearing test execution history and querying the specific field in test class,but nothing worked. 
The formula field is populated with Salesforce 15 digit ID. 
siddharth-Panditsiddharth-Pandit
Hi Shital, I disagree with your statement that your below query doesn't fetch the name.

newCollP = [SELECT Id,SObject2__r.SObject1__r.Name, Col_Type__C from SObject3__C where Id=:newCollP.id];

Just add a debug "newCollp.Col_Type__c" right below your query in test class to see the result.
If still it didn't work then share your complete code here.

-Sid
Shital SonkusaleShital Sonkusale
Hi all,
We have got the issue. SObject1 is a managed package object. Whenever we create SObject1, the managed package code changed it's name to created record's Id. However the change takes some time to reflect when created in a test class. That's why after inserting SObject1,when I queried it's name through soql it returned name as 'Name-3312'. But when using the formula field on sobject3, the name was already replaced by Id of sobject1 and hence it the formula field returned ID ,not the name. The managed package code wasn't caught in debug logs ,so took a long time to figure out whatsw happening.

Thank you all for your help, I am closing this thread now.
This was selected as the best answer