function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
T-S.comT-S.com 

Trigger test class error - null object reference

Hello, 

 

I've written a test class for my trigger, but it doesn't work correctly because it always references a null object.

 

@isTest

private class Trigger_Test{

static testMethod void testInsert() {

Object1__c myObject1 = new Object1__c (name = '123', status__c = 'A');
Object2__c myObject2 = new Object2__c (name = 'John Doe');
Object3__c myObject3 = new Object3__c(Object1__c = myObject1.Id, Object2__c = myObject2.Id, date__c = datetime.now()); // should launch trigger that changes myObject1.status__c = 'X'

insert myObject1;
insert myObject2;

System.debug('Object3 name ' + myObject3.name + ' Object1 ' + myObject3.Object1__c + ' Object2 ' + myObject3.Object2__c);

insert myObject3;

System.assertEquals('X', [SELECT status__c FROM Object1__c WHERE id =: myObject1.id].status__c);

}

}

 

 

Already the system debug displays that myObject3 doesn't exist (all references are null) and assert then naturally fails.

 

Thanks in advance for any help!

Best Answer chosen by Admin (Salesforce Developers) 
T-S.comT-S.com

All Answers

OyeCodeOyeCode

Here is something spooky

 

System.debug('Object3 name ' + myObject3.name + ' Object1 ' + myObject3.Object1__c + ' Object2 ' + myObject3.Object2__c);

 

System.debug - will try to print the myObject3.name before the data table (object in other words) in committed. henforth if you try inserting the myObject3 by relocating a line above - it should work

 

Change like this

 

insert myObject2;

System.debug('Object3 name ' + myObject3.name + ' Object1 ' + myObject3.Object1__c + ' Object2 ' + myObject3.Object2__c);

insert myObject3; 

 

 

to actually

insert myObject2;
insert myObject3;

System.debug('Object3 name ' + myObject3.name + ' Object1 ' + myObject3.Object1__c + ' Object2 ' + myObject3.Object2__c);

 

Let us know, if you find a hope

T-S.comT-S.com

Hi,

 

thanks for the proposal - there you're totally right, but the trigger test class still unfortunately doesn't work. Following error occurs:

 

Error MessageSystem.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, BI_Rental_CheckAssetStatus: execution of BeforeInsert

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

Trigger.BI_Rental_CheckAssetStatus: line 8, column 1: []
Stack TraceClass.Trigger_AI_Rental_SetAssetStatus_Test.testInsert: line 13, column 1

 

 

Test class:

@isTest

private class Trigger_AI_Rental_SetAssetStatus_Test{

    static testMethod void testInsert() {

        Asset__c     myAsset     = new Asset__c (name = '9878173283722', status__c = 'Available');
        Borrower__c  myBorrower  = new Borrower__c (name = 'Jones Joe', active__c = true);
        Rental__c    myRental    = new Rental__c(asset__c = myAsset.Id, borrower__c = myBorrower.Id, pickup_date__c = datetime.now());

        insert myAsset;
        insert myBorrower;
        insert myRental;        // this command fails
        
        System.debug('Time ' + datetime.now());
        System.debug('Asset name ' + myAsset.name + ' status ' + myAsset.status__c);
        System.debug('Borrower name ' + myBorrower.name + ' status ' + myBorrower.active__c);        
        System.debug('Rental name ' + myRental.name + ' asset ' + myRental.asset__c + ' borrower ' + myRental.borrower__c);

        System.assertEquals(myAsset.id, myRental.asset__c);        
        System.assertEquals(myBorrower.id, myRental.borrower__c);        

 

 

Trigger where test class fails:

 

trigger BI_Rental_CheckAssetStatus on Rental__c (before insert) {


// Disables to rent assets with other status than Available.
// Disables to rent assets that have been already discarded.

    for(Rental__c myRental : trigger.new){

        Asset__c myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; // there the test class fails
    
        if(myAsset.status__c != 'Available'){
            myRental.addError('You cannot borrow asset, which has a different status than Available. Current asset status is ' + myAsset.status__c + '.');
        }

    }

}

 

 

 

 

Thanks in advance for any help :)

OyeCodeOyeCode

This will throw an error because

 

    Asset__c myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; 

 

 here you are trying to access the field of myAsset (Asset__C) type object which is not instantiated

 

Possible solution

 

    Asset__c myAsset = new Asset__C([SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]);

 

Let me know if this helps


T-S.comT-S.com

Thanks for the proposal.

 

It unfortunately didn't help, because saving of adjusted trigger fails and following error message appears:

 

Error: Compile Error: SObject constructor must use name=value pairs at line 8 column 28

 

Do you have any ideas, why?

 

Thanks in advance

OyeCodeOyeCode

Lets figure this out step by step

 

Asset__c myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; // there the test class fails

 

Now we have quierd uncommitted object called myAsset (while pull some rows with dataset)

 

Now let instantiate in next the Asset object by passing this value

 

So :  Asset(myAsset)      -- error line  ( SObject constructor must use name=value pairs )

 

Clearly as error manifest that for instantiating the object contructor requires name, value pairs hence something like this could help 

 

Asset(myAsset, value)     where myAsset is name and value is something to be required  (hmm tricky but what) it could be something that the Asset is trying to point to - 'Could be Rental__c  in your case so something like this

 

But here you have be carefully so wait again

 

myAsset is Asset type while the value of Rental__C will be id - hence lets to parameter match

 

so

 

Asset__c myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; // there the test class fails

 

new Asset(Rental__C.id == myAsset.id)

 

 

Very equally likely something needs to be added after you pieace of code

 

 

Asset__c myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; // there the test class fails

 

new Asset(Rental__C.id == myAsset.id)

 


T-S.comT-S.com

Hi,

 

the issue isn't in the trigger itself, because if I test it manually on the same data then everything works fine.

 

Even if I rewrite the trigger to following:

 

Asset__c myAsset = new Asset__c();
myAsset = [SELECT status__c FROM Asset__c WHERE Id = :myRental.Asset__c]; 

 

the test class fails like above.

 

What seems really funny is the failure message - which according the sfdc documentation means that I don't have sufficient access rights (see: http://kb.omni-ts.com/entry/68/ ) to create the test record. That's naturally a rubish, because I run the code as system admin.

 

Any ideas in this direction?

 

Thanks again and have a nice weekend.

T-S.comT-S.com
This was selected as the best answer
OyeCodeOyeCode

The solution is actually two step

    Asset__c     myAsset     = new Asset__c (name = '9878173283722', status__c = 'Available'); 

 

1. you forgot to add 'new' which you were not doing it before (hence insert before activity popped and DML exception was thrown

 

2. You forgot to commit data which is proposed by inserting the data

 

3. Key-Value pair issue in another one (which pop's up when you need key-value pair of this data type)

 

Solution was discussed here in steps the questions kept on changing :-)

 


OyeCodeOyeCode

Based on title of the post

 

 

'null Object reference' was you never instantiated using 'new'