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
tsalbtsalb 

Test Class help - Assert child record matches to each parent after automated insertion

I've used a pretty awesome trigger template, and I've tested that the trigger behavior is working as expected (knock on wood). I took it from a peer's blog (http://blog.deadlypenguin.com/blog/2012/02/13/classifying-triggers-in-salesforce/) and it's working well.

 

The logic of the trigger automatically inserts child records (Vendor_Scorecard__c) lookup to the parent (Service_Request__c) if Service Request is in Status of 'In Review'.

 

I'm having trouble on the test class, I need to query for the existence of child VSCs and assert that they inserted properly, but i'm not sure how. I also have another issue from a pre-existing trigger (too many SOQL) but i'm not sure why it hits the limit.

 

This tests a lot of triggers...and some are poorly written so I can't set test data over 5 records or it fails (that's another problem, not for today). How would I query for the created Vendor_Scorecard__c for each of the srf's in the list?

 

static testMethod void addVendorIdTest() {   
	
	//Create test Task Order
	Task_Order__c t = new Task_Order__c(Name = 'Test Task Order');
	Insert t;	       
	
	//Create test Account
	Account a = new Account(Name = 'Test', Task_Order__c = t.Id, Lin__c = '9999');
	Insert a;
   
	//Create test Contact
	Contact c = new Contact(LastName = 'Test', AccountId = a.Id, Vendor_Id__c = '123ABC');
	Insert c; 
	
	//Create test Service Request BULK
	List <Service_Request__c> srfTestList = new List <Service_Request__c>();
	  for (integer i=0; i<5; i++) {
		Service_Request__c sr = new Service_Request__c(
			Task_Order__c = t.Id, 
			Vendor_Id__c = '123ABC', 
			Status__c = 'New'
		);
		  srfTestList.add(sr);
	  }
			
	  insert srfTestList;
	  
	  test.startTest();  
	  for(Service_Request__c srf: srfTestList) {
		srf.Status__c = 'In Review';
		update srf;  	
	  }
	  test.stopTest();
				
	List <Service_Request__c> insertedSRFs = [Select Vendor_Name__c, Id FROM Service_Request__c WHERE Id IN: srfTestList];
	
	String testVendor = [SELECT Vendor_Name__c FROM Service_Request__c WHERE Id = :srfTestList LIMIT 1].Vendor_Name__c;
	
	for (Service_Request__c s: insertedSRFs){
	  System.assertEquals(c.Id, testVendor);
	}
	
}

 

This is the method (classified trigger) that creates the Vendor_Scorecard__c objects for each srf in srfList. Ignore the excessive comments, that's for me...

 

public void doAwesomeness() {
	
	if (isUpdate) {
		
	  set<Id> objIds = new Set<Id>();
	  
	  for (Service_Request__c srf: newObjs) {
		if (
			oldMap.get(srf.ID) != null &&
			oldMap.get(srf.ID).Status__c != srf.Status__c &&
			srf.Status__c == 'In Review'
		) {
		  //Set for unique IDs for records that pass conditionals above 
			objIds.add(srf.Id);
		}
	  }
	  
	  //Maybe don't need where Status statement, since it's done above?
	  //List is to house records that have passed conditions above		  
	  List <Service_Request__c> srfList =
		[SELECT Status__c, Id, Vendor_Name__c
		 FROM Service_Request__c
		 WHERE Status__c = 'In Review'
		 AND Id IN: objIds];
	  
	  //List for update of VSCs added, for each of the srf in the list above
	  List<Vendor_Scorecard__c> vscList = new List<Vendor_Scorecard__c>();

	  //for records in list, iterate through and use values from those records to create new child VSCs
	  for (Service_Request__c srf: srfList){
		Vendor_Scorecard__c vsc = new Vendor_Scorecard__c (
			Service_Request__c = srf.Id, 
			Vendor__c = srf.Vendor_Name__c,
			RecordTypeId = '012800000007dww');
		vscList.add(vsc);
	  }
	  if (!vscList.isEmpty()) {
		try {
		  insert vscList;
		} catch (DmlException e) {}
	  }
	//End Routing Boolean, return necessary?     
	} else {
	  return;
	}
}

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
dmchengdmcheng

If there are other triggers and they are poorly written like you say, then you probably need to fix them or disable them so you can determine what problems are actually being caused by your own code.

All Answers

tsalbtsalb

Definitely need some help...I'm not understanding how to iterate through 5 records (of which each now has a child record) and then assert that each child has its parent lookup Id.

 

After the update, There should be 5 Vendor_Scorecard__c for each of the Service_Request__c in the srfTestList - I'm not sure how to go about asserting each of them, that they all 

 

a) have a lookup ID in the master-detail field (Service_Request__c)

b) that the parent ID matches in order of which they were created? I guess i basically want to assert each child went to the right parent.

 

This returns an ID mismatch? Also, is there a way to loop through these without declaring [0], [1], etc.

 

static testMethod void addVendorIdTest() {   
	
	//Create test Task Order
	Task_Order__c t = new Task_Order__c(Name = 'Test Task Order');
	Insert t;	       
	
	//Create test Account
	Account a = new Account(Name = 'Test', Task_Order__c = t.Id, Lin__c = '9999');
	Insert a;
   
	//Create test Contact
	Contact c = new Contact(LastName = 'Test', AccountId = a.Id, Vendor_Id__c = '123ABC');
	Insert c; 
	
	//Create test Service Request BULK
	List <Service_Request__c> srfTestList = new List <Service_Request__c>();
	  for (integer i=0; i<5; i++) {
		Service_Request__c sr = new Service_Request__c(
			Task_Order__c = t.Id, 
			Vendor_Id__c = '123ABC', 
			Status__c = 'New'
		);
		  srfTestList.add(sr);
	  }
			
	  insert srfTestList;
	  
	  for(Service_Request__c srf: srfTestList) {
		srf.Status__c = 'In Review'; 	
	  }
	  
	  test.startTest();
	  update srfTestList;
	  test.stopTest();
	  
	Map <Id, Service_Request__c> SRFmap = new Map <Id, Service_Request__c>(srfTestList);
		
	List <Service_Request__c> insertedSRFs = 
		[SELECT Vendor_Name__c, Id 
		 FROM Service_Request__c 
		 WHERE Id IN: SRFmap.keySet()];
		 
	List <Vendor_Scorecard__c > insertedVSCs = 
		[SELECT Service_Request__c, Id 
		 FROM Vendor_Scorecard__c
		 WHERE Service_Request__c IN: SRFmap.keySet()];
		 
	Map <Id, Vendor_Scorecard__c> VSCmap = new Map <Id, Vendor_Scorecard__c>(insertedVSCs);
	
	String testVendor = 
		[SELECT Vendor_Name__c
		 FROM Service_Request__c
		 WHERE Id = :srfTestList LIMIT 1].Vendor_Name__c;
	 
	for (Service_Request__c s: insertedSRFs) {
	  System.assertEquals(
		c.Id,
		testVendor
	  );
	}
	
	for (Vendor_Scorecard__c v: insertedVSCs) {
	  System.assertEquals(
		SRFmap.get(srfTestList[0].Id).Id,
		VSCmap.get(insertedVSCs[0].Id).Id
	  );
	}
	
} 		

 

tsalbtsalb

Oh my. Completly overlooked this.

 

The change below worked, but still - is there a way to "iterate" through the entire set of 5 records?

 

	
	for (Vendor_Scorecard__c v: insertedVSCs) {
	  System.assertEquals(
		SRFmap.get(insertedSRFs[0].Id).Id,
		VSCmap.get(insertedVSCs[0].Id).Service_Request__c
	  );
	}
	

 

Also, i'm not understanding why this fails on the [1] assert, even if i change both my InsertedVSCs and Inserted SRFs to 'ORDER BY Created Date ASC'

 

	    for (Vendor_Scorecard__c v: insertedVSCs) {
	      System.assertEquals(
	      	SRFmap.get(insertedSRFs[0].Id).Id,
	      	VSCmap.get(insertedVSCs[0].Id).Service_Request__c
	      );
//FAILS HERE  System.assertEquals(
//ID MISMATCH   SRFmap.get(insertedSRFs[1].Id).Id,
	        VSCmap.get(insertedVSCs[1].Id).Service_Request__c
	      );
	    }

 

dmchengdmcheng

I don't have time now to read through all your code, but have you considered using SOQL relationship queries to get all the scorecard records for a service request, then asserting the size() of the scorecard list for each svc req?

 

http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_relationships.htm

tsalbtsalb

I think that could work, but woudln't it be a less precise test than trying to assertEqual(child.lookupToParentId, parent.Id)?

 

I guess what i'm asking is, isn't it better to test that each child was inserted to the correct parent, rather than just a parent - which list size would imply. It would be better documentation (in my mind) that way too.

dmchengdmcheng

If you want to assert each scorecard, then do a relationship query on the Service Request and include the Scorecards, then iterate through the service requests and inside the loop iterate through the scorecard card records for each svc request.

 

 

for(svcReq__c req : SvcReqList) {
	for(Scorecard__c sc : SvcReqList.Scorecards) {
	}
}

 

 

tsalbtsalb

Alright, so I'm not sure what's going on - but I think i need some conceptual help here. If I create a test list of 150 Service Requests, I fail the test ( last system.assertEquals) frequently (1 out of 3 tries using apex testrunner)

 

HOWEVER

 

if i change the sample size to i < 50 (smaller list) I don't fail in 10 runs - what is going on?!

 

	    List <Service_Request__c> srfTestList = new List <Service_Request__c>();
	      for (integer i=0; i<150; i++) {
	    	Service_Request__c sr = new Service_Request__c(
	    		Task_Order__c = t.Id, 
	    		Vendor_Id__c = '123ABC', 
	    		Status__c = 'New'
	    	);
	    	  srfTestList.add(sr);
	      }
	    		
	      insert srfTestList;
	      
	      for(Service_Request__c srf: srfTestList) {
	        srf.Status__c = 'In Review'; 	
	      }
	      
	      test.startTest();
	      update srfTestList;
	      test.stopTest();
	      
	    Map <Id, Service_Request__c> SRFmap = new Map <Id, Service_Request__c>(srfTestList);
 	        
	    List <Service_Request__c> insertedSRFs = 
	    	[SELECT Vendor_Name__c, Id 
	    	 FROM Service_Request__c 
	    	 WHERE Id IN: SRFmap.keySet()];
	    	 
	    List <Vendor_Scorecard__c > insertedVSCs = 
	    	[SELECT Service_Request__c, Id 
	    	 FROM Vendor_Scorecard__c
	    	 WHERE Service_Request__c IN: SRFmap.keySet()];
	    	 
	    Map <Id, Vendor_Scorecard__c> VSCmap = new Map <Id, Vendor_Scorecard__c>(insertedVSCs);
	    
	    String testVendor = 
	    	[SELECT Vendor_Name__c
	    	 FROM Service_Request__c
	    	 WHERE Id = :srfTestList LIMIT 1].Vendor_Name__c;
	     
	    //Vendor_Id__c correctly matched the corresponding contact and placed onto the SRF
  		System.assertEquals(c.Id, testVendor);

		//One Vendor Scorecard per SRF
		System.assertEquals(insertedSRFs.size(), insertedVSCs.size());
		
		//All child's lookup to the correct parent in order of insertion
		for (integer i=0; i<insertedSRFs.size(); i++) {
			System.assertEquals(
			  SRFmap.get(insertedSRFs[i].Id).Id, 
			  VSCmap.get(insertedVSCs[i].Id).Service_Request__c
			);
		}

 

 

 

dmchengdmcheng

If there are other triggers and they are poorly written like you say, then you probably need to fix them or disable them so you can determine what problems are actually being caused by your own code.

This was selected as the best answer