2

I have a before insert trigger. In this trigger I am comparing a formula field which references the family of the product with a hardcoded value. If they match I display an error message.

When run from the UI, this seems to work—the family name field holds the correct value—but when run from a test class the formula field is null.

Is there a reason for this?

Test:

Product2 p1 = new Product2(
    Name = 'test Product1', Standard_Discount_Rate__c = 10, Family = 'Hardware',
    Transaction_Type__c = 'New', Quotable__c = true, IsActive = true);

try
{
    insert p1;
    System.debug('Product1  inserted.' + p1.family);
}
catch (Exception e)
{
    System.debug('Error inserting Product1: ' + e.getDmlMessage(0));
}

Pricebook2 pb = [SELECT Id, Name FROM Pricebook2 WHERE IsStandard = true LIMIT 1];
pb.IsActive = true;

try
{
    update pb;
}
catch (Exception e)
{
    System.debug('Error updating Pricebook: ' + e.getDmlMessage(0));
}

PricebookEntry pbe = new PricebookEntry(
    Pricebook2Id = pb.Id, Product2Id = p1.Id, UnitPrice = 200,
    UseStandardPrice = false, IsActive = true);

try
{
    insert pbe;
}
catch (Exception e)
{
    System.debug('Error inserting PricebookEntry: ' + e.getDmlMessage(0));
}

Quote q = new Quote(
    Name = 'test quote', OpportunityId = o.Id, Status = 'Draft',
    ExpirationDate = Date.today(), Pricebook2Id = pb.Id);
insert q;

QuoteLineItem qli = new QuoteLineItem(
    QuoteId = q.Id, PricebookEntryId = pbe.Id, Quantity = 1,
    Discount = 6, UnitPrice = 200);
insert qli;

Product_Family__c is a formula field in QuoteLineItem with the formula TEXT(Product2.Family).

Before trigger on QuoteLineItem:

for (QuoteLineItem qli : Trigger.new)
{       
    System.debug('Product_family__c ' + qli.Product_Family__c); // This shows null in test class but shows the family when running from UI.
    if (qli.Product_Family__c == 'Hardware')
    // Do something
}
5
  • 2
    Can you provide the test code to reproduce the problem? Does the formula field reference data through a lookup relationship which is null in your test scenario?
    – Mark Pond
    Commented Jul 3, 2013 at 17:46
  • isnt't the problem that this is a before trigger? Before the record is committed to the database the value won't be there
    – Doug B
    Commented Jul 4, 2013 at 6:01
  • @DougB But i get the value on productFamily__c when running through UI.
    – Prady
    Commented Jul 4, 2013 at 7:48
  • In the UI when you save and refresh it has already gone through before and after triggers. Try your code in an after trigger and see what it looks like?
    – Doug B
    Commented Jul 4, 2013 at 9:03
  • @DougB what i meant was the code is working as expected. The only issue is when i run the test class that i dont find the value. The debug logs show a null while running the test class, but shows the correct values while running it from UI. I am not sure as to why there is a behavioural change while running from test class and UI. It could be the way i set the test class but cant figure out what
    – Prady
    Commented Jul 5, 2013 at 4:03

2 Answers 2

3

I guess the top block of code is the test class and the bottom is the trigger.

Formula fields are are calculated at query time. After you insert the quote line item, query for it, selecting the formula field value and it should work out.

3
  • Can i query the inserting/updating record on a before trigger?
    – Prady
    Commented Aug 6, 2013 at 4:37
  • No, I mean after you insert it in the unit test. It wont have the formula value until you query for it.
    – Phil Rymek
    Commented Aug 6, 2013 at 12:18
  • Had this exact issue, I inserted the SO object but forgot to query for the formula field and it evaluated to null in my test class. Commented Mar 10, 2014 at 15:55
2

It depends on when you are expecting the field to be updated. Formula fields based on the record's values will not be updated until well after the trigger has been run (see the Order of Execution.)

Given your explanation, though, it sounds like you may not be populating your test data correctly. If you can share your code we can provide you with a more thorough answer.

1
  • 1
    I think this answer is misleading because the linked article does not mention formula fields. Furthermore formula fields are not calculated in any order, rather they are calculated on the fly as apart of the query and will reflect whatever values are in the database in real time.
    – Phil Rymek
    Commented Aug 5, 2013 at 16:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .