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
RstrunkRstrunk 

Trouble with Test Class for this Trigger

Hello All, 

   I'll start off by saying I'm not the best coder in the world(as you will see below :-p ) but I have written triggers and test classes in the past.  I wrote this trigger below and for the life of me, I can't write a test class that gets more than 25% code coverage.  I don't know why.  In previous attempts at the test class I feel like I coded for the appropriate scenarios, yet some of the lines still remain red.  So I wanted to come here and just post the trigger to see someone elses take on a test class for it.  Maybe I have been doing things really wrong.  

 

Here is the trigger:

 

trigger standardChange on Case(before insert, before update){

  if(trigger.isBefore && trigger.isInsert){
    if(StandardChange_Helper.ranFlag == false){
      set<ID> ParentCases = new Set<ID>();
      list<Case> SoqlParentResults = new list<case>();

      for(case tmpCase:trigger.new){
        if(tmpCase.Standard_Change_Related_Case__c != null && tmpCase.type == 'Change'){
          ParentCases.add(tmpCase.Standard_Change_Related_Case__c);
        }
      }
      SoqlParentResults = [Select id, Standard_Change_Related_Case__c FROM Case c WHERE ((c.ID IN:ParentCases) or (c.Standard_Change_Related_Case__c IN:ParentCases))];

      For(Integer i = 0; i < trigger.new.size(); i++){
        if(trigger.new[i].type == 'Change' && trigger.new[i].Standard_Change_Related_Case__c != null){
          Integer subCaseCount = 0;
          for(Integer counter = 0; counter < soqlParentResults.size(); counter++){
            if(trigger.new[i].Standard_Change_Related_Case__c == soqlParentResults.get(counter).id ){
              subCaseCount += 1;
            }
            else if(soqlParentResults.get(counter).Standard_Change_Related_Case__c == trigger.new[i].Standard_Change_Related_Case__c){
              subCaseCount += 1;
            }
          }
          trigger.new[i].Standard_Change_Request_Iteration__c = (subCaseCount + 1);
        }
      }
      StandardChange_Helper.ranFlag = true;
    }
  }
  else if(trigger.isBefore && trigger.isupdate){
    if(StandardChange_Helper.ranFlag == false){
      set<ID> ParentCases = new set<ID>();
      list<Case> SoqlParentResults = new list<case>();

      for(case tmpCase:trigger.new){
        if(tmpCase.Standard_Change_Related_Case__c != null && tmpCase.type == 'Change'){
          ParentCases.add(tmpCase.Standard_Change_Related_Case__c);
        }
      }

      SoqlParentResults = [Select id, Standard_Change_Related_Case__c FROM Case c WHERE ((c.ID IN:ParentCases) or (c.Standard_Change_Related_Case__r.id IN:ParentCases))];    

      For(Integer i = 0; i < trigger.new.size(); i++){
        if(trigger.new[i].type == 'Change'){
          //if parent case was just deleted
          if(trigger.new[i].Standard_Change_Related_Case__c == null && trigger.old[i].Standard_Change_Related_Case__c != null){               
            trigger.new[i].Standard_Change_Request_Iteration__c = 0;
          }
          //there is a parent case and there was not before
          else if(trigger.new[i].Standard_Change_Related_Case__c != null && trigger.old[i].Standard_Change_Related_Case__c == null){              
            Integer subCaseCount = 0;
            for(Integer counter = 0; counter < soqlParentResults.size(); counter++){
              if(trigger.new[i].Standard_Change_Related_Case__c == soqlParentResults.get(counter).id ){
                system.debug('before subcasecount = :' + subCaseCount);
                subCaseCount += 1;
                system.debug('after subcasecount = :' + subCaseCount);
              }
              else if(soqlParentResults.get(counter).Standard_Change_Related_Case__c == trigger.new[i].Standard_Change_Related_Case__c){
                subCaseCount += 1;
              }
            }               
            trigger.new[i].Standard_Change_Request_Iteration__c = subCaseCount + 1;             
          }
          //old parent field had a value and new parent field also has a value
          else if(trigger.new[i].Standard_Change_Related_Case__c != null && trigger.old[i].Standard_Change_Related_Case__c != null){
            //parent has not changed
            if(trigger.new[i].Standard_Change_Related_Case__c == trigger.old[i].Standard_Change_Related_Case__c){
              /*  COMMENTED OUT TO KEEP THE ITERATION NUMBER THE SAME AS WHAT IT WAS INITIALLY SET TO.  
              THIS WILL PREVENT THE ITERATION NUMBER FROM CHANGING IF THE STANDARD CHANGE PARENT DOES
              NOT CHANGE AND ADDITTIONAL CASES HAVE BEEN ADDED AS SUBCASES.  

              Integer subCaseCount = 0;
              for(Integer counter = 0; counter < soqlParentResults.size(); counter++){
                if(trigger.new[i].Standard_Change_Related_Case__c == soqlParentResults[counter].id ){
                  subCaseCount += 1;
                }
              }
              trigger.new[i].Standard_Change_Request_Iteration__c = subCaseCount;
              */
            }
            //When parent case has been changed to a new case
            else{
              Integer subCaseCount = 0;
              for(Integer counter = 0; counter < soqlParentResults.size(); counter++){
                if(trigger.new[i].Standard_Change_Related_Case__c == soqlParentResults[counter].id ){
                  subCaseCount +=1;
                }
                else if(soqlParentResults.get(counter).Standard_Change_Related_Case__c == trigger.new[i].Standard_Change_Related_Case__c){
                  subCaseCount += 1;
                }
              }
              trigger.new[i].Standard_Change_Request_Iteration__c = subCaseCount + 1;
            }
          }
        }
      }
      StandardChange_Helper.ranFlag = true;
    }
  }
}

 

 If anyone decides to give it a shot I really appreciate your time and effort!

 

Thanks, 

 

Robert 

Certified Adminstrator

Certified Developer

 

Best Answer chosen by Admin (Salesforce Developers) 
GlynAGlynA

Robert,

 

I see a possible problem with the first part of your test method:

 

    list<case> parentCases = new list<case>();
    set<id> parentIDs = new set<id>();
    parentCases = setupParentCases();
    for(case tmpCase:parentCases){
        parentIDs.add(tmpCase.Standard_Change_Related_Case__c);   
    }
    parentCases = [select id from case where id in:parentCases];

The method 'setupParentCases()' doesn't initialize the 'Standard_Change_Related_Case__c' field, and the trigger does not set it either.  This means that the 'parentIDs' set will contain only one value, 'null'.  Then, the query will get all Cases whose 'Standard_Change_Related_Case__c' field is null.  Because you're using 'seeAllData = true', this could be a large number of Cases.

 

The query isn't really necessary, because you already have the parent records, and the remainder of the test only needs their IDs, which were populated by the 'insert'.  Below is my version of the test class which doesn't use 'seeAllData = true' and doesn't do the unnecessary query.  I'm not able to run and test my code, but I think it should fully cover the trigger.  Let me know if this doesn't do the trick.

 

@isTest
public class TestStandardChange
{
    static List<Case> setupParentCases()
    {
        List<Case> parentCases = new List<Case>();

        for ( Integer i = 0; i < 3; i++ )
        {
            parentCases.add
            (   new Case
                (   Type            = 'Change',
                    Area_1__c       = 'test',
                    Category_1__c   = 'test',
                    Status          = 'new',
                    Priority        = 'Normal',
                    Subject         = 'test',
                    Description     = 'test'
                )
            );
        }
        insert parentCases;
        return parentCases;
    }

    static testMethod void standardChange()
    {
        List<Case> parentCases = setupParentCases();

        List<Case> newCases = new List<Case>();

        for ( Integer i = 0; i < 3; i++ )
        {
            newCases.add
            (   new Case
                (   Type            = 'Change',
                    Area_1__c       = 'test',
                    Category_1__c   = 'test',
                    Status          = 'new',
                    Priority        = 'Normal',
                    Subject         = 'test',
                    Description     = 'test',

                    Standard_Change_Related_Case__c = parentCases[i].Id
                )
            );
            System.debug( 'newCases StandardChangeRelatedCase ID is: ' + parentCases[i].Id );
        }

        Test.startTest();
        try
        {
            insert newCases;
        }
        catch ( Exception e )
        {
            System.debug( 'TestFailure on inserting of standardChange cases' );
        }
        Test.stopTest();
    }
}

 

-Glyn

All Answers

digamber.prasaddigamber.prasad

Hi,

 

Could you also share your test class?

GlynAGlynA

Robert,

 

Instead of writing a test class, I have refactored your trigger.  I believe this does everything that your original code does, but it uses some techniques that allow the same functionality in many fewer lines of code.  Hopefully, this will allow your existing tests to cover most or all of the code.  Please let me know if you have any questions about the code in the refactored trigger.

 

And of course, if this works for you, please mark this as a solution; and give kudos (click on the star) if you think I deserve them.  Thanks!

 

-Glyn

 

trigger standardChange on Case ( before insert, before update )
{
    if ( StandardChange_Helper.ranFlag ) return;

    Set<ID> ParentCases = new Set<ID>();

    for ( Case tmpCase : trigger.new )
    {
        if ( tmpCase.Type != 'Change' || tmpCase.Standard_Change_Related_Case__c == null ) continue;

        ParentCases.add( tmpCase.Standard_Change_Related_Case__c );
    }

    List<Case> SoqlParentResults =
        [   SELECT  Id, Standard_Change_Related_Case__c
            FROM    Case
            WHERE   (   ID IN :ParentCases
                    OR  Standard_Change_Related_Case__c IN :ParentCases
                    )
        ];

    for ( Case theCase : trigger.new )
    {
        if ( theCase.type != 'Change' ) continue;

        Case prevCase = trigger.isUpdate ? trigger.oldMap.get( theCase.Id ) : null;

        //  there is no parent case (on insert) or it was deleted (on update)
        if  (   theCase.Standard_Change_Related_Case__c == null
            &&  (   prevCase == null
                ||  prevCase.Standard_Change_Related_Case__c != null
                )
            )
        {
            theCase.Standard_Change_Request_Iteration__c = 0;
        }

        //  there is a parent case (on insert) or it was added or changed (on update)
        if  (   theCase.Standard_Change_Related_Case__c != null
            &&  (   prevCase == null
                ||  prevCase.Standard_Change_Related_Case__c == null
                ||  theCase.Standard_Change_Related_Case__c != prevCase.Standard_Change_Related_Case__c
                )
            )
        {
            theCase.Standard_Change_Request_Iteration__c = 1;
            for ( Case parentCase : soqlParentResults )
            {
                if  (   theCase.Standard_Change_Related_Case__c == parentCase.id
                    ||  theCase.Standard_Change_Related_Case__c == parentCase.Standard_Change_Related_Case__c
                    )   theCase.Standard_Change_Request_Iteration__c++;
            }
        }
    }
    StandardChange_Helper.ranFlag = true;
}

 

RstrunkRstrunk

TestClass is: 

 

@isTest(seeAllData = true)
public class TestStandardChange{
	static list<Case> setupParentCases(){
		//user owner1 = new user();
		//owner1 CC_UnitTests_Helper.createUser('System Administrator');
		list<Case> parentCases = new list<case>();
		for(integer i = 0; i < 3; i++){
			case tmpCase = new case();
			//tmpCase.area__c = 'test';
			//tmpCase.Category__c = 'test';
			tmpCase.Area_1__c = 'test';
			tmpCase.Category_1__c = 'test';
			tmpCase.type = 'Change';
			tmpCase.Status = 'new';
			tmpCase.Priority = 'Normal';
			tmpCase.Subject = 'test';
			tmpCase.Description = 'test';
			
			parentCases.add(tmpCase);
		}
		insert parentCases;
		return parentCases;
	}
	static testMethod void standardChange(){
		list<case> parentCases = new list<case>();
        set<id> parentIDs = new set<id>();
		parentCases = setupParentCases();
        for(case tmpCase:parentCases){
         	parentIDs.add(tmpCase.Standard_Change_Related_Case__c);   
        }
		parentCases = [select id from case where id in:parentCases];
		
		list<Case> newCases = new list<case>();
		for(integer i = 0; i < 3; i++){
			case tmpCase = new case();
			//tmpCase.area__c = 'test';
			//tmpCase.Category__c = 'test';
			tmpCase.Area_1__c = 'test';
			tmpCase.Category_1__c = 'test';
			tmpCase.type = 'Change';
			tmpCase.Status = 'new';
			tmpCase.Priority = 'Normal';
			tmpCase.Subject = 'test';
			tmpCase.Description = 'test';
			tmpCase.Standard_Change_Related_Case__c = parentCases[i].id;
			
			newCases.add(tmpCase);
		}
		test.startTest();
		try{
			for(case tmp:newCases){
				system.debug('newCases StandardChangeRelatedCase ID is: ' + tmp.Standard_Change_Related_Case__c);
			}
			insert newCases;
		}
		catch(exception e){
			system.debug('TestFailure on inserting of standardChange cases');
		}
		test.StopTest();
	}
}

 

GlynAGlynA

Robert,

 

I see a possible problem with the first part of your test method:

 

    list<case> parentCases = new list<case>();
    set<id> parentIDs = new set<id>();
    parentCases = setupParentCases();
    for(case tmpCase:parentCases){
        parentIDs.add(tmpCase.Standard_Change_Related_Case__c);   
    }
    parentCases = [select id from case where id in:parentCases];

The method 'setupParentCases()' doesn't initialize the 'Standard_Change_Related_Case__c' field, and the trigger does not set it either.  This means that the 'parentIDs' set will contain only one value, 'null'.  Then, the query will get all Cases whose 'Standard_Change_Related_Case__c' field is null.  Because you're using 'seeAllData = true', this could be a large number of Cases.

 

The query isn't really necessary, because you already have the parent records, and the remainder of the test only needs their IDs, which were populated by the 'insert'.  Below is my version of the test class which doesn't use 'seeAllData = true' and doesn't do the unnecessary query.  I'm not able to run and test my code, but I think it should fully cover the trigger.  Let me know if this doesn't do the trick.

 

@isTest
public class TestStandardChange
{
    static List<Case> setupParentCases()
    {
        List<Case> parentCases = new List<Case>();

        for ( Integer i = 0; i < 3; i++ )
        {
            parentCases.add
            (   new Case
                (   Type            = 'Change',
                    Area_1__c       = 'test',
                    Category_1__c   = 'test',
                    Status          = 'new',
                    Priority        = 'Normal',
                    Subject         = 'test',
                    Description     = 'test'
                )
            );
        }
        insert parentCases;
        return parentCases;
    }

    static testMethod void standardChange()
    {
        List<Case> parentCases = setupParentCases();

        List<Case> newCases = new List<Case>();

        for ( Integer i = 0; i < 3; i++ )
        {
            newCases.add
            (   new Case
                (   Type            = 'Change',
                    Area_1__c       = 'test',
                    Category_1__c   = 'test',
                    Status          = 'new',
                    Priority        = 'Normal',
                    Subject         = 'test',
                    Description     = 'test',

                    Standard_Change_Related_Case__c = parentCases[i].Id
                )
            );
            System.debug( 'newCases StandardChangeRelatedCase ID is: ' + parentCases[i].Id );
        }

        Test.startTest();
        try
        {
            insert newCases;
        }
        catch ( Exception e )
        {
            System.debug( 'TestFailure on inserting of standardChange cases' );
        }
        Test.stopTest();
    }
}

 

-Glyn

This was selected as the best answer