0

I have below trigger on after Insert & Update of Assets which is working fine, but test class is NOT.!! The 2 fields which I am asserting, holds null value. While I was researching in the community, I learned that Product Family field of Assets will be evaluated in Run time only and not available within Test class. Is that the case with 'Product Code' field of Assets also? Or am I doing something wrong?

Trigger

trigger AssetsTrigger on Asset (after insert, after update, after delete, after undelete) {
system.debug('Asset Trigger is invoked');
new AssetLineItemTriggerHandler().run();
}

Apex class that gets invoked from Trigger:

public class AssetLineItemTriggerHandler extends TriggerHandler {

    public override void afterInsert() {
        setAssetProdFamiliesForAccount(Trigger.New);
    }

    public override void afterUpdate() {
        setAssetProdFamiliesForAccount(Trigger.New);
    }

    public override void afterDelete() {
        setAssetProdFamiliesForAccount(Trigger.Old);
    }

    public override void afterUndelete() {
        setAssetProdFamiliesForAccount(Trigger.Old);
    }

    // =====
    // Private functions
    // =====


    @TestVisible
    private void setAssetProdFamiliesForAccount(List<Asset> strAsset) {
        Set<Id> AccIDs = new Set<Id>();
        for(Asset pAsset : strAsset) {
            if (pAsset.AccountID != null) {
                AccIDs.add(pAsset.AccountID);
            }
        }
        if (AccIDs.size() > 0) {
            List<Account> Acc = [SELECT Id FROM Account WHERE Id IN :AccIDs];
            Util_Account.setProductFamiliesOfAsset(Acc);
            update Acc;
        }
    }

}

Apex Class:

public with sharing class Util_Account 
{
  public static void setProductFamiliesOfAsset(List<Account> Acc) 
    {
        Map<Id,Account> accsWithParentAssets = new Map<Id,Account>([SELECT Id, (SELECT Id, ProductFamily,ProductCode FROM Assets) FROM Account WHERE Id IN :Acc]);
        for(Account act : Acc) 
        {
            Account completeAccount = accsWithParentAssets.get(act.Id);
            Set<String> productFamilies = new Set<String>();
            Set<String> ProductCodes = new Set<String>();
            for(Asset ast : completeAccount.Assets) {
                if (ast.ProductFamily != null) {
                    productFamilies.add(ast.ProductFamily);
                    ProductCodes.add(ast.ProductCode);
                }
            }
            act.Asset_Product_Families__c = null;
            act.Asset_Product_Codes__c = null;
            if (productFamilies.size() > 0) {
                act.Asset_Product_Families__c = String.join(new List<String>(productFamilies), ',');
            }
            if(ProductCodes.size() > 0)
            {
                act.Asset_Product_Codes__c = String.join(new List<String>(ProductCodes),',');
            }
        }
    }

}

Test Class:

@IsTest public class AssetLineItemTriggerHandlerTest {

@IsTest
public static void setAssetProdFamiliesForAccount() {
    Account a = new Account(Name='testacc1',Country__c = 'Slovakia',ShippingCountry = 'Slovakia',Country_Code__c = 'SK');
    insert a;
    
    Product2 prd = new Product2(Name='Product1', Family='fam1', ProductCode='RMS2345');
    insert prd;
     Asset ast = new Asset(Name='ass1',AccountId=a.Id,Price=100,Product2=prd,Quantity=1,Percentage_of_Maintenance__c=10);
    insert ast;
    a = [select ID, Asset_Product_Codes__c,Asset_Product_Families__c from Account where ID=:a.Id];
    system.assertEquals('RMS2345', a.Asset_Product_Codes__c);
    System.assertEquals('fam1', a.Asset_Product_Families__c);
    
}

}

4
  • 1
    please define "not working" where does the test class fail? Use edit
    – cropredy
    Commented Sep 24, 2020 at 22:55
  • I am sorry, the 2 fields which I am asserting, holds null value. While I was researching in the community, I learned that Product Family field of Assets will be evaluated in Run time only and not available in Test classes. Is that the case with 'Product Code' field of Assets also? Or am I doing something wrong?
    – Amulya
    Commented Sep 25, 2020 at 1:15
  • In the "setProductFamiliesOfAsset" method, can you do a system.debug to check if the "accsWithParentAssets" map variable is empty or not after you have initialized it?
    – Jason Fung
    Commented Sep 25, 2020 at 16:08
  • It has Account ID & Asset ID. But ProductCode & ProductFamily are null.
    – Amulya
    Commented Sep 25, 2020 at 18:47

1 Answer 1

1

I've had issues in the past with these convenience fields on Standard objects that are in effect, formula fields on the related Product2.

A worthwhile experiment is to change this query:

Map<Id,Account> accsWithParentAssets = 
   new Map<Id,Account>([SELECT Id, (SELECT Id, ProductFamily,ProductCode FROM Assets) 
                            FROM Account WHERE Id IN :Acc]);

to:

Map<Id,Account> accsWithParentAssets = 
    new Map<Id,Account>([SELECT Id, 
                          (SELECT Id, Product2.ProductFamily, Product2.ProductCode FROM Assets) 
                            FROM Account WHERE Id IN :Acc]);
           
3
  • No it didn't help, I had tried before. Regular code is working fine, just test class doesn't have visibility to Product fields, looks like.!!
    – Amulya
    Commented Sep 29, 2020 at 18:13
  • What version is testclass?
    – cropredy
    Commented Sep 29, 2020 at 19:32
  • API version is 50.
    – Amulya
    Commented Sep 29, 2020 at 21:15

You must log in to answer this question.

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