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
NiknitNiknit 

Why am i not able to insert test data in my Test class?

About trigger :There are two objects student_details__c and department__c. department__c - contains name and no_of_students__c; student_details__c contains name, department(lookup to department object).
when a student is inserted in a department, that respective department needs to increment the no_of_students__field,similarly when department is changed of a student from one dept to other then no_of_students__c needs to be incremented in the new department and decremented from the old department field. no_of_student__c is the total count of students in respect to the department the belong to in each department object.

Testclass
@istest

private class StudentupdatehandlerTestClass {

    static testMethod void validateupdatechange() {

       Department__c  newdept = new department__c();   
       newdept.name='CSE';
       insert newdept;

       student_details__c newstudent = new Student_details__c();

       newstudent.Name='From TestClass';   
       newstudent.department__c = newdept.id;    



       System.debug('before@@trigger: ' + newdept.no_of_students__c);

       insert newstudent;

       newstudent = [SELECT department__c FROM student_details__c WHERE Id =:newstudent.Id];
       System.debug('after@@trigger: ' + newdept.no_of_students__c);


       System.assertEquals(1 , newdept.no_of_students__c);
    }
}

error is in the insert newstudent line

Trigger
trigger Test on Student_Details__c (after insert, after update,after delete) {

        studentupdatehandler studobj = new studentupdatehandler();

        if(trigger.isinsert)
        {
        studobj.afterinsert(trigger.new);
        }

        if(trigger.isdelete)
        {
        studobj.afterdelete(trigger.old);
        }

       if(trigger.isupdate)
       {
       studobj.afterupdate(trigger.new,trigger.old);
       }    
}

Triggerhandler
 
public class studentupdatehandler{

     set<id> deptid = new set<id>();  

public void afterinsert(student_details__c[] newstudentslist) {

        list<department__c> newdeptlist = [select id,name,no_of_students__c,(select id from student_details__r) from department__c where id in:forids(newstudentslist)];

        toinsert(newdeptlist);
 } 

     public void afterdelete(student_details__c[] oldstudentslist) {
        list<department__c> olddeptlist = [select id,name,no_of_students__c,(select id from student_details__r) from department__c where id in:forids(oldstudentslist)];

        toupdate(olddeptlist);
 }

    public void afterupdate(student_details__c[] newstudentslist,student_details__c[] oldstudentslist) {

        list<department__c> newdeptlist = [select id,name,no_of_students__c,(select id from student_details__r) from department__c where id in:forids(newstudentslist)];
        toinsert(newdeptlist);


        list<department__c> odeptlist= [select id,name,no_of_students__c,(select id from student_details__r) from department__c where id in:forids(oldstudentslist)];
        toupdate(odeptlist);  

}

Public set<id> forids(student_details__c[] deptlist ){
        set<id> ids = new set<id>();

         for(student_Details__c record: deptlist){

             ids.add(record.Department__c);

            }
return ids;}

Public void toinsert(department__c[] deptlist ){

        for(department__c dept : deptlist){

                   dept.no_of_students__c = dept.no_of_students__c +1;
        }                 
   update deptlist;      
        } 

Public void toupdate(department__c[] odeptlist ){


        for(department__c dept : odeptlist){
                 dept.no_of_students__c = dept.no_of_students__c -1;
             } 
         update odeptlist; 
}


}


I need to create test case for insert, update and delete.

The problem is I am not bale to input data for the student object for the lookup field in it,Department is another object which is lookup in the student object with field department__c,

I feel i am not populating that field in correct manner in test class.

Best Answer chosen by Niknit
Asif Ali MAsif Ali M
Now it makes sense why the error is occurring. Generally as a best practise it would be nice to have a default value 0 on number type fields unless you have a special meaning for null on department__c.no_of_students__c.

Here is the code to to test record update.
 
@istest
private class StudentupdatehandlerTestClass {
    
 @istest
    static void validateupdatechange() {
     

      Department__c  newdept = new department__c();   
      newdept.name='CSE';
      newdept.no_of_students__c=0;
      
      insert newdept;

       newDept = [SELECT Id, no_of_students__c FROM Department__c LIMIT 1];
       student_details__c newstudent = new Student_details__c();
       newstudent.Name='FromTestClass';   
       newstudent.department__c = newdept.id;    
       insert newstudent;

        // CHANGE in SOQL FILTER
       newDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:newDept.Id];  
 
       System.assertEquals(1 , newdept.no_of_students__c);

      // NEW CODE
      Department__c  anotherDept = new department__c();   
      anotherDept.name='Another Department';
      anotherDept.no_of_students__c=0;

      insert anotherDept;

      newstudent.department__c = anotherDept.Id;
      update newstudent;

       newDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:newDept.Id];  
 
       System.assertEquals(0 , newdept.no_of_students__c);

       anotherDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:anotherDept.Id];  
 
       System.assertEquals(1 , anotherDept.no_of_students__c);


    }
}

 

All Answers

Asif Ali MAsif Ali M
Can you provide the error messag to understand the problem better?
unless there is a specific reason for LOOKUP relation between  department__c and student_details__c I would suggest you to change the relation to Master-Detail and use the Roll-Up-Summray fields (https://help.salesforce.com/articleView?id=fields_defining_summary_fields.htm&type=0&language=en_US) to let the platform calculate department__c.no_of_students__c for you
NiknitNiknit

Oops, sorry i thought i had already added the rror message.

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Test: execution of AfterInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
Class.studentupdatehandler.toinsert: line 61, column 1 Class.studentupdatehandler.afterinsert: line 12, column 1 Trigger.Test: line 12, column 1: []



The line " newstudent.department__c = newdept.id; " in the test class is what causes the error, the test class passes if i comment that line.

Asif Ali MAsif Ali M
Seems like the newdept is not getting saved. Can you put a debug statement after Insert newdept;  and see what newdept contains.
system.debug('Department' + newdept);

 
NiknitNiknit

Hi @Asif

 

I did try that, it seems it is getting inserted. it shows all values of department as inserted.

Asif Ali MAsif Ali M
May be the deptlist is empty. Can you check the size of deptlist in toinsert method?
NiknitNiknit

Hi @Asif

I tried with the below statement in the toinsert()

 System.debug('@@@@@deplist ' + deptlist);

 

it shows the department entered in the Testclass.

"19:40:03:037 USER_DEBUG [54]|DEBUG|@@@@@deplist (Department__c:{Id=a0Q7F000000pH05UAE, Name=CSE, No_of_Students__c=0})"

Asif Ali MAsif Ali M
Then it must be something on Student_details__c object causing the issue.
Did you try manually adding record into Student_details__c with a lookup to DEPT ? 
NiknitNiknit

I thought i am manually adding the student_details__c record with lookup tp dept from below lines

 student_details__c newstudent = new Student_details__c();
       
           newstudent.Name='From TestClass';  
           newstudent.department__c = newdept.id;   

Asif Ali MAsif Ali M
I meant to use Salesforce Interface to insert records. What happens if you try to insert the record in student? 
NiknitNiknit

Hi @Asif ,

The test is running now, the test passes.

the following is the code
 

@istest
private class StudentupdatehandlerTestClass {
    
 @istest
    static void validateupdatechange() {
     

      Department__c  newdept = new department__c();   
      newdept.name='CSE';
      newdept.no_of_students__c=0;
      
      insert newdept;

       newDept = [SELECT Id, no_of_students__c FROM Department__c LIMIT 1];
       student_details__c newstudent = new Student_details__c();
       newstudent.Name='FromTestClass';   
       newstudent.department__c = newdept.id;    
       insert newstudent;

       newDept = [SELECT Id, no_of_students__c FROM Department__c LIMIT 1];  
 
       System.assertEquals(1 , newdept.no_of_students__c);
    }
}

 

How do i test for update, i can delete the record and check for delete but how do i test for update method , what code do i add to test the update method, Can you please help on that update matter please.Thanks you for giving me time and helping me out in this little issue.

Asif Ali MAsif Ali M
Now it makes sense why the error is occurring. Generally as a best practise it would be nice to have a default value 0 on number type fields unless you have a special meaning for null on department__c.no_of_students__c.

Here is the code to to test record update.
 
@istest
private class StudentupdatehandlerTestClass {
    
 @istest
    static void validateupdatechange() {
     

      Department__c  newdept = new department__c();   
      newdept.name='CSE';
      newdept.no_of_students__c=0;
      
      insert newdept;

       newDept = [SELECT Id, no_of_students__c FROM Department__c LIMIT 1];
       student_details__c newstudent = new Student_details__c();
       newstudent.Name='FromTestClass';   
       newstudent.department__c = newdept.id;    
       insert newstudent;

        // CHANGE in SOQL FILTER
       newDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:newDept.Id];  
 
       System.assertEquals(1 , newdept.no_of_students__c);

      // NEW CODE
      Department__c  anotherDept = new department__c();   
      anotherDept.name='Another Department';
      anotherDept.no_of_students__c=0;

      insert anotherDept;

      newstudent.department__c = anotherDept.Id;
      update newstudent;

       newDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:newDept.Id];  
 
       System.assertEquals(0 , newdept.no_of_students__c);

       anotherDept = [SELECT Id, no_of_students__c FROM Department__c where Id=:anotherDept.Id];  
 
       System.assertEquals(1 , anotherDept.no_of_students__c);


    }
}

 
This was selected as the best answer
NiknitNiknit
Thank you Asif for the big help.
NiknitNiknit

Hi Asif, can you please tell me why we are using where Id=:newDept.Id in the SOQL query , when i don't use it test fails, why is it needed?

I was trying to make it on my own, as follows but it fails on update method

 

@istest

private class StudenthandlerTestClass {
    
      
      @testSetup
           static void testData(){
        
                list<student_details__c> studlist = new list<student_details__c>();
                list<department__c> deptlist = new list<department__c>();
                for(integer i=0;i<2;i++){
                    Department__c  newdept = new department__c();   
                    newdept.name='dept'+i;
                    newdept.no_of_students__c=0;  
                    deptlist.add(newdept);
                }
            insert deptlist;
                   
                for(integer i=0;i<2;i++){
                   student_details__c newstudent = new Student_details__c();
                   newstudent.Name='Student'+i;   
                   newstudent.department__c = deptlist[i].id;    
                   studlist.add(newstudent);
                  }
            insert studlist;
           
           
           }
    
    
      @istest
           static void validateinsert() {
      
                  list<department__c> deptlist = [SELECT Id, no_of_students__c FROM Department__c];
 
                  list<student_details__c> studlist = new list<student_details__c>();  

                  deptlist = [SELECT Id,name, no_of_students__c FROM Department__c];  

                    for(integer i=0;i<2;i++){
                       System.assertEquals('dept'+i , deptlist[i].name);
                       System.assertEquals(1 , deptlist[i].no_of_students__c);
                               }
                  }
     
     
       @istest
           static void validateupdate() {
                  list<department__c> deptlist = [SELECT Id, name,no_of_students__c FROM Department__c];
                  list<student_details__c> studlist = [SELECT Id,name, department__c FROM student_details__c];    
 
                       System.assertEquals(1 , deptlist[1].no_of_students__c);
                       System.assertEquals(1 , deptlist[0].no_of_students__c);
                    
                       studlist[0].department__c = deptlist[1].id;
                       update studlist; 
                       deptlist = [SELECT Id, name,no_of_students__c FROM Department__c ];
                       System.assertEquals(1 , deptlist[1].no_of_students__c);
                       System.assertEquals(1 , deptlist[0].no_of_students__c);
            
            }
}
Asif Ali MAsif Ali M
Hi Nitin,

Your initial code worked without any filter because you were only inserting single record. After I updated the code with additional Dept insert I need to make sure I am picking the right dept record so the filter on Id. If I dont put the filter I ll get any random record and my Assertions will fail.

 
NiknitNiknit
oh, now i am undertstanding, how does newDept = [SELECT Id, no_of_students__c FROM Department__c LIMIT 1]; help, i mean LIMIT.wouldn't it fetch the first record only each time this query is run.if i insert more than one record then this query won't help me right?I guess I am just confused when to use LIMIT , I know why it is used as a query but i am not able to understand in what scenario it suits best as it will get only the first record according to me.
Asif Ali MAsif Ali M
LIMIT 1 is based on the Order BY clause. By default I guess the system will fetch you FIRST record (ORDER BY Id ASC) but this is not a best way to do it specially when your test method is inserting many rows and you need to retrive them again for assertions. You should always fetch based on IDs otherwise your tests will fail.
Kristen RhamesKristen Rhames
“Data created or selected to satisfy the execution preconditions and input content required to execute one or more test cases.” There is a lot of attention for testing methods like security testing, performance testing or regression testing.
valid data - sensible, possible data that the program should accept and be able to process.
extreme data - valid data that falls at the boundary of any possible ranges.
invalid (erroneous) data - data that (https://exams.com.pk/) the program cannot process and should not accept.