0

I am trying to depoy a change set and my apext test class is failing and giving this error message:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateTermsFromAcc: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.UpdateTermsFromAcc: line 34, column 1: []

Here is my apex test class:

@IsTest(SeeAllData = true)
private class AccountandOpportunitiesTests {

    static testMethod void myTest() {

        Profile p = [select id from profile where name='System Administrator'];
        User user = new User(alias = 'standt', email='testuser@clondalkintest.com',
            emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',
            localesidkey='en_US', profileid = p.Id,
            timezonesidkey='America/Los_Angeles', username='testuser@clondalkintest.com');
        insert user;

        PageReference pageRef = Page.AccountsAndOpportunities;
        Test.setCurrentPage(pageRef);
        ApexPages.currentPage().getParameters().put('sfdc.userId', user.Id);

        System.runAs(user) {
        Account account = new Account(Name = 'testAccount');
        insert account;

        Opportunity opportunity = new Opportunity(Name = 'test opportunity', StageName = 'Prospecting', CloseDate = system.today().addDays(1));
        insert opportunity;

        accountsAndOpportunitiesController ctrl = new accountsAndOpportunitiesController();
        system.assertEquals(1, ctrl.userAccounts.size(), 'One record should be returned');
        }
    }
 }

Here is my Controller for the test

public with sharing class accountsAndOpportunitiesController {
    
    public list<userAccount> userAccounts {get;set;}
    public list<Account> accounts {get;set;}
    public Boolean showAccounts {get;set;}
    public Boolean showOpportunities {get;set;}

    public accountsAndOpportunitiesController() {
        showAccounts = false;
        showOpportunities = false;
        map <String, list<Opportunity>> accountswithOppMap = new map <String, list<Opportunity>>();
        map<String, Id> accountIdsMap = new map<String, Id>();
        Id userId = ApexPages.currentPage().getParameters().get('sfdc.userId');
        list<Opportunity> opportunities = [SELECT AccountId, Account.Name, Name, Revenue_Yr_3__c, StageName, CloseDate FROM Opportunity WHERE OwnerId = :UserId AND IsClosed = false order by Account.Name, Name];
        accounts = [Select Name FROM Account WHERE OwnerId = :UserId order by Name];
        
        if (opportunities.size() > 0) {
            showOpportunities = true;
        }
        
        if (accounts.size() > 0) {
            showAccounts = true;
        }

        for(Opportunity opp :opportunities) {
            list<Opportunity> opps = new list<Opportunity>();
            if(accountswithOppMap.containsKey(opp.Account.Name) == true) opps = accountswithOppMap.get(opp.Account.Name);
            opps.add(opp);
            accountswithOppMap.put(opp.Account.Name, opps);
            accountIdsMap.put(opp.Account.Name, opp.AccountId);
        }
        
        userAccounts = new list<userAccount>();
        
        for(String myAccount :accountswithOppMap.keyset()) {
            userAccount myUserAccount = new userAccount();
            myUserAccount.AccountName = myAccount;
            if(accountIdsMap.containsKey(myAccount) == true)myUserAccount.AccountId = accountIdsMap.get(myAccount);
            myUserAccount.opportunities = new list<Opportunity>();
            if(accountswithOppMap.containsKey(myAccount) == true) myUserAccount.opportunities = accountswithOppMap.get(myAccount);
            userACcounts.add(myUserAccount);
        }
    }
    
    public class userAccount {
        public String AccountName {get;set;}
        public Id AccountId {get;set;}
        public list<Opportunity> opportunities {get;set;}
    }
    
   }

Here is my trigger:

trigger UpdateTermsFromAcc on Opportunity (before insert, after insert) {


    if(trigger.isbefore){
        set<id> Userset = new Set<id>();
        set<id> Accset = new Set<id>();
        for(Opportunity opp:trigger.new){
            Accset.add(opp.accountid);  
            Userset.add(opp.ownerid);
        }
        
        Map<id,account> aMap = new Map<id,account>([SELECT id,name,terms__c,owner.id, OWNERID FROM ACCOUNT WHERE id IN :Accset]);
        
        system.debug(Userset);
        
        /*
        List<User> u = [SELECT id,UserRole.name from User WHERE id IN:Userset];
        Map<ID,String> UserRoleMap = new Map<ID,String>();
        for(User us:u){
            UserRoleMap.put(us.id,us.UserRole.name);
        }
        system.debug(UserRoleMap);
        */
        Map<Id, Recordtype> rtMap = new Map<Id, Recordtype>([SELECT id,name FROM recordtype WHERE SOBJECTTYPE = 'OPPORTUNITY']);
        RecordType rec;
        String UAF_RT_ID = '012U0000000QW6e';
        for (RecordType r : rtMap.values()){
          if (r.Name == 'Global Filter Opportunities'){
            rec = r;
          }
        }
        
        for(Opportunity opp:trigger.new){
            opp.terms__c = amap.get(opp.accountid).terms__c;
            if(opp.recordtypeid == rec.id && opp.Assign_Owner__c != null){
                opp.ownerid = opp.Assign_Owner__c;
            }
                    
            //if(opp.recordtypeid == rec.id && UserRolemap.get(opp.ownerid).contains('GF -')){
            //    opp.ownerid = acc.ownerid;
            //}        
            
            //2014-11-24 default UAF oppty owner to account owner
            else if (opp.recordtypeid == UAF_RT_ID && Trigger.isInsert){
              if (aMap.containsKey(opp.AccountId)){
                opp.OwnerId = aMap.get(opp.AccountId).OwnerId;
              }
            }
        }
    }   
    
    
    if(trigger.isafter){
    RecordType rect = [SELECT id,name FROM recordtype WHERE name = 'Global Filter Tasks'];
    List<Task> TaskList = new List<Task>();

        Set<id> idset = new set<id>();
        set<id> Userset = new Set<id>();
        set<id> Createdset = new Set<id>();
        for(Opportunity opp:trigger.new){
            idset.add(opp.accountid);
            //Userset.add(opp.ownerid);
            //Createdset.add(opp.createdbyid);
        }
        
        /*
        List<User> u = [SELECT id,UserRole.name from User WHERE id IN:Userset];
        Map<ID,String> UserRoleMap = new Map<ID,String>();
        for(User us:u){
            UserRoleMap.put(us.id,us.UserRole.name);
        }
        
        List<User> c = [SELECT id,UserRole.name from User WHERE id IN:Createdset];
        Map<ID,String> CreatedRoleMap = new Map<ID,String>();
        for(User us:c){
            CreatedRoleMap.put(us.id,us.UserRole.name);
        }
        */
        List<Account> AccList = [SELECT id,name FROM account WHERE id IN: idset];
        
        map<id,string> AccMap = new map<id,string>();
        for(Account acc:AccList){
        accmap.put(acc.id,acc.name);
        }
        
        RecordType rec = [SELECT id,name FROM recordtype WHERE name = 'Global Filter Opportunities'];
                
        for(Opportunity opp:trigger.new){
            if(opp.recordtypeid == rec.id && opp.Assign_Owner__c != null){ //&& CreatedRoleMap.get(opp.createdbyid).contains('GF -') && opp.Stage_Reason__c == 'Price Request Only'){ // && !UserRolemap.get(opp.ownerid).contains('GF -')){
                Task t = new Task();
                t.whatid = opp.id;
                t.Subject = 'Follow up on new Oppty for '+ accmap.get(opp.accountid);
                t.Ownerid = opp.Assign_Owner__c;
                t.type = 'Follow-Up';
                t.RecordTypeid = rect.id;
                t.priority = 'High';
                t.ActivityDate = date.today();
                TaskList.add(t);
            }
        }
        
        Database.DMLOptions dlo = new Database.DMLOptions();
        dlo.EmailHeader.triggerUserEmail= true;
        database.insert(TaskList, dlo);
        //Insert TaskList;
    }
    
    
    
    
}
  • 1
    The error comes from a trigger called UpdateTermsFromAcc. Please post the code from this trigger. – Martin Lezer Jul 26 '17 at 13:25
  • Check to make sure rec isn't null? – zgc7009 Jul 26 '17 at 13:45
  • I think that it comes from the fact that you didn't link an Account to the opportunity in your test. Whereas, on this line: opp.terms__c = amap.get(opp.accountid).terms__c;, you're trying to get an element in a Map using the opportunity accountId. This map is empty because there were no account linked to the opportunities. So amap.get(opp.accountid) returns null. – Martin Lezer Jul 26 '17 at 13:45
  • Thank you Martin. What should I add to my code to bring in a account id. – Khylin Edwards Jul 26 '17 at 13:59
  • You should fix the bug in your trigger first, and check if the value of your get is null before fixing your test. – battery.cord Jul 26 '17 at 14:21
1

Fix these lines in your test:

Opportunity opportunity = new Opportunity(Name = 'test opportunity', 
    StageName = 'Prospecting', CloseDate = system.today().addDays(1));
insert opportunity;

To:

Opportunity opportunity = new Opportunity(Name = 'test opportunity', 
    StageName = 'Prospecting', CloseDate = system.today().addDays(1),
    AccountId = account.Id);
insert opportunity;
1

You already have a null check lower in your code. But on 34, you do not include this protection.

Missing Null Check

opp.terms__c = amap.get(opp.accountid).terms__c;

Proper Null Check

if (aMap.containsKey(opp.AccountId)){
    opp.OwnerId = aMap.get(opp.AccountId).OwnerId;
}

Here you know you would never have a key with a null value, but for maps constructed by hand, it might be worth checking you actually get a value back rather than just that the key exists. That would look a little different:

for (Opportunity record : trigger.new)
{
    Account parentAccount = aMap.get(record.AccountId);
    if (parentAccount != null)
    {
        // set terms
    }
    // remainder of loop logic
}
  • Thanks Adrian, Is this code change going into the trigger or test class? – Khylin Edwards Jul 26 '17 at 14:22
  • The trigger. You need to add a null check where you set the terms. You have actually uncovered a bug in your own code, which is exactly what the tests are there for! – Adrian Larson Jul 26 '17 at 14:23
  • @KhylinEdwards Both of these answers are correct. You are missing the null check, as the account was not getting set on the opportunity. Even though setting the account fixes this test error, you should also add the null checks posted by Adrian Larson – JRiffe Jul 26 '17 at 14:32
  • @JRiffe Without fixing the trigger, the bug will remain. I disagree that fixing the test alone is even a little bit correct. – Adrian Larson Jul 26 '17 at 14:33
  • 1
    @AdrianLarson Yes, for code correctness, I very much agree. But that fixed their specific error they were asking about. – JRiffe Jul 26 '17 at 14:34

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.