5

i have written a test class where i am comparing 2 fields. One of that fields is related to a formula field in an opportunity. More in detail: One field in the opportunity is filled by formula with a value from the linked account. This field is called 'Source_Details__c' in both, opp and acc.

here is the formula: "text( Account.Source_Details__c )" the field in Opportunity is called same 'Source_Details__c'

Another field in the opportunity will be filled with a trigger, based on that formula field. When i run a test class, i need to have the formula field to be filled, but it seems, that field is not filled, does a testclass not run formula fields? Maybe i should add the error message here:

System.QueryException: List has no rows for assignment to SObject

here is the trigger

trigger update_related_Supplier on Opportunity (before insert, before update) 
{ 
    for (Opportunity opp: Trigger.new) 
    { 
        if(opp.Source_Details__c != null)
        { 
            Account[] acc = [Select Id from Account where Name = :opp.Source_Details__c] ; 
            if(acc.size() > 0)
            { 
                opp.related_Partner_Supplier__c = acc[0].Id;
            } 
            else 
            { 
                opp.related_Partner_Supplier__c = null; 
            }
        }
    }
}

and here is the test class

    @IsTest
    public class TestClassOppCaseStore {
static testMethod void TestClassOppCaseStore_trigger(){
Account a = new Account(Name = 'testAccount',
                        BillingPostalCode = '83059',
                       BillingCountry = 'Deutschland',
                       Source_Details__c = 'Düren (Saturn)');
insert a; 
Lead l = new Lead (LastName = 'Musterhausen',
                   Country = 'Deutschland',
                   Company = 'MeierEisen',
                   PostalCode = '12457',
                   LeadSource = 'Import',
                   Status = 'new');
insert l;

Event k = new Event (Subject = 'Testing',
                     WhoId = l.Id,
                     StartDateTime = date.today(),
                    EndDateTime = date.today());
    insert k;

Event m = new Event (Subject = 'Testing',
                     WhatId = a.Id,
                     StartDateTime = date.today(),
                    EndDateTime = date.today());
    insert m;

Task t = new Task (Subject = 'Demotermin',
                   WhatId = a.Id);
 insert t;

Task u = new Task (Subject = 'Demotermin',
                   WhoId = l.Id);
 insert u;

    Pricebook2 d = new Pricebook2 (Name = 'Standard');
insert d;
Product2 e =new Product2 (Name = 'Top AG',
                          VK_netto__c = 12);
insert e;
        Opportunity g = new Opportunity (Name = 'testOpp',
                                  AccountId = a.Id,
                                 Amount = 250,
                                 StageName = 'new',
                                 CloseDate = date.today(),
                                 related_Partner_Supplier__c = a.Id);
    insert g;
    update a;
    update g;
CKSW_BASE__Service__c serv = new CKSW_BASE__Service__c (Opportunity__c = g.Id,
                                                       CKSW_BASE__Account__c = a.Id,
                                                       CKSW_BASE__Status__c = 'new');
insert serv;
Case c = new Case (Subject = g.Name,
                  AccountId = a.Id,
                  related_Partner_Supplier__c = a.Id);
insert c;
g = [SELECT Account.Id, Source_Details__c FROM Opportunity WHERE Id = :g.Id];
System.AssertEquals(a.Id, g.AccountID);
Account ag = [SELECT Id FROM Account WHERE Name = :g.Source_Details__c];
System.AssertEquals(ag.Id, g.related_Partner_Supplier__c);
c = [SELECT Account.Id, Account_Source_Details__c FROM Case WHERE Id = :c.Id];
System.AssertEquals(a.Id, c.AccountID);
Account ac = [SELECT Id FROM Account WHERE Name = :c.Account_Source_Details__c];
System.AssertEquals(ac.Id, c.related_Partner_Supplier__c);}}
5
  • 2
    would you add the trigger code and refer how you have used the formula field in trigger Commented May 19, 2017 at 20:37
  • here is the formula: "text( Account.Source_Details__c )" the field in Opportunity is called same 'Source_Details__c' Commented May 19, 2017 at 20:45
  • here is the trigger: >trigger update_related_Supplier on Opportunity (before insert, before update) { for (Opportunity opp: Trigger.new) { if(opp.Source_Details__c != null){ Account[] acc = [Select Id from Account where Name = :opp.Source_Details__c] ; if(acc.size() > 0){ opp.related_Partner_Supplier__c = acc[0].Id;} else { opp.related_Partner_Supplier__c = null; }}}} Commented May 19, 2017 at 20:46
  • edited the question Commented May 19, 2017 at 20:53
  • A useful feature is the sObject method recalculateFormulas() developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… as long as they are not cross-object formulas
    – Eric
    Commented May 20, 2017 at 2:27

2 Answers 2

3

Formula field is calculated on the fly and the values will be available after record is committed to database.

Before saving the Opportunity ie. in before insert and update, you are checking Opportunity values, which are not available.

So, in this case, related_Partner_Supplier__c is always null.

2nd thing, your trigger is not bulkified. It is always taking first account's id.

3rd thing, you have unnecessarily used DML statements in test method:

    Opportunity g = new Opportunity (Name = 'testOpp',
                              AccountId = a.Id,
                             Amount = 250,
                             StageName = 'new',
                             CloseDate = date.today(),
                             related_Partner_Supplier__c = a.Id);
insert g;
update a; //why it is needed?
update g; //why it is needed?

Explanations of this error in the following lines of code:

g = [SELECT Account.Id, Source_Details__c FROM Opportunity WHERE Id = :g.Id];
System.AssertEquals(a.Id, g.AccountID);
Account ag = [SELECT Id FROM Account WHERE Name = :g.Source_Details__c];

Source_Details__c of Opportunity is null due to your inappropriate logic in trigger, which is getting passed to retrive Account record.

By default, Account Name is mandatory so it cannot be null, But here due to query condition no records are returning.

That's why, in this below line Account ag = [SELECT Id FROM Account WHERE Name = :g.Source_Details__c];, you are getting that error

System.QueryException: List has no rows for assignment to SObject.

Workaround, perform the formula field value checking in after insert and after update of Opportunity trigger.

Hope it makes sense.

10
  • thx a lot for your reply. but i have a 'update g' call in the test class, shouldnt that get the values meanwhile? Commented May 19, 2017 at 21:44
  • No, it will not, Ideally, you should create a record that will test your trigger or other code logic Commented May 19, 2017 at 21:45
  • ok, but then i do not understand how to perform the formula field value check in after insert and after update of opp trigger, what to do you mean whith that? Commented May 19, 2017 at 21:46
  • I have tested the triggers plenty times with existing opps as well as creating new opps, its working very well Commented May 19, 2017 at 21:49
  • 1
    Let us continue this discussion in chat. Commented May 20, 2017 at 1:58
1

in the end, after checking again the test class, i found the error myself. eventhough, Santanu gave some valuable replies, i updated the class as following and it works. even with the formula field and nothing else changed.

here is the test class change

static testMethod void TestClassOppCaseStore_trigger(){
Account a = new Account(Name = 'Düren (Saturn)',
                        BillingPostalCode = '83059',

I simply had the wrong name in the account name, so of course, nothing could be found in the test class

7
  • Thats a good catch, nice to see your issue solved Commented May 20, 2017 at 2:41
  • One thing I would say, trigger you have written is incorrect logic, you need to work on that. Whether you will change or not thats upto you Commented May 20, 2017 at 2:49
  • can you please let me know, which logic is incorrect, i have never learned coding, this is all experienced on the going. Commented May 20, 2017 at 20:20
  • trigger logic when you are checking formula value is incorrect Commented May 20, 2017 at 20:21
  • can you please be a bit more detailed? am curious about that Commented May 20, 2017 at 20:22

You must log in to answer this question.

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