0

My apex consists of an trigger and an apex class. My test class continues to fail with System.NullPointerException: Attempt to de-reference a null object

Trigger:

trigger PQ_Update on ProdQueue__c (after update) 
{    
    Set<ID> ids = Trigger.newMap.keySet();
    List<ProdQueue__c> pq = [SELECT Id, Listing__c, Listing__r.id, Status__c, OM_Approve__c, Producer__c FROM ProdQueue__c WHERE id in :ids];
    system.debug('pq');
    if(pq.size()>0){
        PQ_Update.updatePQ(pq);
    }
}

Apex:

public class PQ_Update 
{
    public static void updatePQ(List<ProdQueue__c> pq)
    { 
        List<Listing__c> ls= new list<Listing__c>();
        for(ProdQueue__c i : pq)
        {
            ls.add(i.Listing__r);
            for (Listing__c l : ls)
            {
                l.Producer__c=i.Producer__c;
                l.Production_Status__c=i.Status__c;             
                l.OM_Approve__c=i.OM_Approve__c;                  
            }
        }    
        update ls;
    }
}

Test Class:

@isTest
public class PQ_UpdateTEST {
     public static testMethod void updatePQ(){
        Property__c pro = new Property__c();
        insert pro;        

        Listing__c l = new Listing__c (
            Name = 'Test Name',
            Already_Converted__c = 'Not Converted',
            Property__c = pro.id,
            Probability__c = 50,
            Sale_Price__c = 8888888888.00,
            Commission_Input__c = 9999.99,
            Asking_Price__c = 1777777777,
            Down_Payment__c = 55555555,
            Mortgage_Amount__c = 444444,
            Occupancy_at_Close__c = 333,
            Transaction_Notes__c = 'TEST TEST',
            Close_Date__c = date.Today(),
            CAP_Rate__c = 9.99,
            Sale_Price_SF__c = 25,
            Lease_Expiration_Date__c = date.Today()
        );
        insert l;

        List<ProdQueue__c> pqList = new List<ProdQueue__c>();
        ProdQueue__c pqOne = new ProdQueue__c(
            Listing__c=l.id,
            Status__c='OM Complete',
            OM_Approve__c='Yes',
            Producer__c='Brian',
            Production_Type__c='OM'
        );

        ProdQueue__c pqTwo = new ProdQueue__c(
            Listing__c=l.id,
            Status__c='OM Complete',
            OM_Approve__c='Yes',
            Producer__c='Brian',
            Production_Type__c='OM'
        );


        pqList.add(pqOne);
        pqList.add(pqTwo);

        insert pqList;

        PQ_Update.updatePQ(pqList);
    }
}
  • Which line are you getting the null pointer exception? – Prady Mar 11 '16 at 0:53
  • l.Production_Status__c=i.Status__c; – MRG Mar 11 '16 at 0:55
  • code coverage also stops here – MRG Mar 11 '16 at 0:56
  • Why are you directly calling PQ_Update.updatePQ(pqList); in your test method when it should just be called through the trigger? And why are you re-querying the ProdQueue__c records in your trigger? – Nick Cook Mar 11 '16 at 1:00
  • What happens if you replace your whole trigger with PQ_Update.updatePQ(trigger.new); ? – Nick Cook Mar 11 '16 at 1:03
3

I'd rewrite this as follows:

Trigger

trigger PQ_Update on ProdQueue__c (after update) {
    PQ_Update.updatePQ(Trigger.new);
}

Handler class

public class PQ_Update {
    public static void updatePQ(List<ProdQueue__c> pqs) {
        map<ID,Listing__c> lIdToListingMap= new map<ID,Listing__c>();
        for(ProdQueue__c pq : pqs) {
            if (pq.listing__c != null)
               lIdToListingMap.put(pq.listing__c,new Listing__c(
                                   id = pq.listing__c,
                                   Producer__c=pq.Producer__c,
                                   Production_Status__c=pq.Status__c,             
                                   OM_Approve__c=pq.OM_Approve__c));                 
        }    
        update lIdToListingMap.values();
    }
}

Based on your test class, you are copying values from PQs into parent Listing__c. Since the trigger has a reference to the parent, you can construct the sobject to be updated from the reference ID Listing__c. No extra SOQL required and no double loops. Also, if two PQs happen to point at the same Listing__c, then the last one in the trigger set will be the 'winner` when it comes to updating the parent Listing. If this is not what you want, the logic needs to get more sophisticated.

I'd also strongly consider renaming the handler method updatePQ to be something like afterUpdateHandler that in turn calls a method enhanceListings or something indicative of the business purpose of this little snippet - since you may have other snippets to add over time that need to be executed when a PQ is updated

And, your testmethod needs asserts to verify that the code does what you expect

  • Thank you! Working great. I haven't used the map methods before...wasn't sure when the appropriate time was to use them, I'll read over the documentation on them now. – MRG Mar 14 '16 at 17:13
  • @MRG if you spend enough time on this forum and study enough of the answers, you'll see that SFDC actually designed Apex to do common things in a fairly concise way - but that the doc doesn't always make these idioms clear. Glad I could help – cropredy Mar 14 '16 at 17:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.