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
Shamrock SnowmanShamrock Snowman 

Test Class for Trigger based on a record update of particular field

I have a ChatUp trigger that posts to a parent object feed when a particular field in the child object is updated.  I copied a test class from a similar trigger, but the one I copied from is based on INSERTING records vs UPDATING them.  How can I modify my test class to not only insert the child object records (Drug Test), but then to UPDATE those records so that the trigger fires? 

 

Here is the trigger:  the Result__c field must have been updated in order to post to the Chatter feed.

 

trigger ChatterDrugTestResultChatUp on Drug_Test__c (after update) {
for (Drug_Test__c newDrugTest : Trigger.new) {
Drug_Test__c oldDrugTest = Trigger.oldMap.get (newDrugTest.Id);
if (oldDrugTest.Result__c != newDrugTest.Result__c){
ChatterUpHelper helper = new ChatterUpHelper();
helper.chatterUp(Trigger.new);
}
}
}

 

 

Here is the TEST CLASS I have so far:

 

@isTest
public class ChatterUpTestDrugTest {
static testMethod void testChatterUpOrder(){
Date today = date.today();
LIST<Drug_Test__c> drugTestList = new LIST<Drug_Test__c>();
Chatter_Up__c settingsChatter = createChatterUpConfig();/*new Chatter_Up__c(Name = 'Drug Test',
Chatter_Post_Body__c = 'A Drug Test result has been posted to this order. Click the link below to view.',
Parent_ID_Field__c = 'Order__c',
Object_API_Name__c = 'Drug_Test__c');*/
insert settingsChatter;

Org_Specific_Values__c settingsOrg = new Org_Specific_Values__c(Name = 'test',
Bypass_Triggers_For_Data_Loading__c = False);
insert settingsOrg;
Tax_Schedule__c t = new Tax_Schedule__c(County__c = 'All State',
State__c = 'Alabama');
insert t;

Account a = new Account(Name = 'Test Account',
Type = 'Prospect',
BillingStreet = 'test',
BillingCity = 'test',
BillingState = 'test',
BillingPostalCode = 'test'
);
insert a;

Contact c = new Contact(LastName = 'Test Contact',
AccountId = a.Id);

Order__c o = new Order__c(Name = 'Test Order',
Client_Name__c = a.Id,
Contact__c = c.Id,
Account_Manager__c = UserInfo.getUserId(),
Status__c = 'Inquiry',
orderType__c = 'New Project',
workState__c = 'Alabama',
Trade__c = 'a1yA0000000EN9z',
Tax_Schedule__c = t.Id,
Requested_Headcount__c = 1,
Project_Start_Date__c = today,
Estimated_Project_End_Date__c = date.newInstance(today.year(),today.month(),28),
Requested_Start_Time__c = '7:00 AM',
Candidate_Submit_Date__c = today
);
insert o;

for(Integer i=0; i < 100; i++){
Drug_Test__c dt = new Drug_Test__c(Order__c = o.Id,
Employee_Name__c = 'a1eA0000000dBmY',
Date_of_Drug_Test__c = today,
Vendor__c = 'Concentra',
Test_Type__c = 'Urine (DOT)',
Number_of_Drugs_Tested__c = '5-Panel');
drugTestList.add(dt);
}
test.startTest();
insert drugTestList;
test.stopTest();
LIST<FeedItem> orderFeed = [SELECT ParentId FROM FeedItem WHERE ParentId = :o.Id];
System.assertEquals(100,orderFeed.size());
}

static private Chatter_Up__c createChatterUpConfig(){
Chatter_Up__c setting = new Chatter_Up__c();

setting.Name = 'Drug Test';
setting.Chatter_Post_Body__c = 'A Drug Test result has been posted to this order. Click the link below to view.';
setting.Parent_ID_Field__c = 'Order__c';
setting.Object_API_Name__c = 'Drug_Test__c';

return setting;
}
}

 

 
Alex.AcostaAlex.Acosta

If your trigger runs only on updates, you first need to get your record into the salesforce right? Once this occurs you can just update the same record. After inserting the Sobject record, your record will now contain an Id value which allows you to update. 

 

Example:

 

Account account = new Account(name='My new account');

// in this case your trigger won't fire off yet because it's an insert

insert account;

 

// repush the record into the system so it's an update and your trigger will fire off

update account;

 

 

Shamrock SnowmanShamrock Snowman

Alex,

Thank you for the reply.  I get what you are saying, but my trigger is looking for one specific field of the record to be updated,  where the Result__c field must be different than its original value.   So, don't I have to dictate that specific change somehow?

Alex.AcostaAlex.Acosta

That is correct. I was just giving you an example.

Shamrock SnowmanShamrock Snowman
Alex, Sorry for the back and forth, but that is the root of my problem - HOW do I dictate that specific update in my test class? Do you have any code examples of updating a specific field in the record? Thank for your help. Dave
Alex.AcostaAlex.Acosta

It's fine...

 

I just don't know what type of field Result__c is. If it's a simple text field you can just change the value...

 

IE: after this...

for(Integer i=0; i < 100; i++){
Drug_Test__c dt = new Drug_Test__c(Order__c = o.Id,
Employee_Name__c = 'a1eA0000000dBmY',
Date_of_Drug_Test__c = today,
Vendor__c = 'Concentra',
Test_Type__c = 'Urine (DOT)',
Number_of_Drugs_Tested__c = '5-Panel',
Result__c = String.valueOf(i)); drugTestList.add(dt); } insert drugTestList;

 

do something like this 

Integer i = drugTestList.size() + 1;
for(Drug_Test__c dt :drugTestList){
	dt.Result__c = String.valueOf(i);
	drugTestList.add(dt);
	i++;
}
test.startTest();
update drugTestList;
test.stopTest();

 

Shamrock SnowmanShamrock Snowman

Alex,

Last question, i promise:

Result__c is a picklist field, where the original record has a value of "Pending," and it gets updated either to "Positive" or "Negative."  That's the change I'm tracking.   

 

So, how do I call for that Picklist instead , where you have "...String.ValueOf()..." ?

 

Thank you so much.

 

Dave

Alex.AcostaAlex.Acosta

Only reason I was using String.valueOf was because the value was original an Integer and I needed to convert it to a string since I was under the assumption of it being a string. 

 

In your case do this then

for(Integer i=0; i < 100; i++){
Drug_Test__c dt = new Drug_Test__c(Order__c = o.Id,
Employee_Name__c = 'a1eA0000000dBmY',
Date_of_Drug_Test__c = today,
Vendor__c = 'Concentra',
Test_Type__c = 'Urine (DOT)',
Number_of_Drugs_Tested__c = '5-Panel',
Result__c = 'Pending'); drugTestList.add(dt); } insert drugTestList;

 

do something like this 

Integer i = 0;
for(Drug_Test__c dt :drugTestList){
String resultValue = 'Positive';
if(i%2 != 0)
resultValue = 'Negative';
dt.Result__c = resultValue; drugTestList.add(dt); i++; } test.startTest(); update drugTestList; test.stopTest();

 

Only reason for the following

     String resultValue = 'Positive';
if(i%2 != 0)
resultValue = 'Negative';

is because i figured you would want to test out both senerios, what this does is if the value 'i' is divisible by 2 it stays as the value positive, otherwise it becomes negative.

Shamrock SnowmanShamrock Snowman

Alex,

Could there be a problem with having the 2 iterations in that code?  I ran the test and received this failure message:

 

System.FinalException: Cannot modify a collection while it is being iterated.

 

Dave

Alex.AcostaAlex.Acosta

Are you setting  Result__c = 'Pending' on the insert?

 

If you are and still getting this error then just get all the Ids from your insert and requery the records back out.

 

IE:

 

Set<Id> idList = new Set<Id>();
for(Drug_Test__c dt :drugTestList){
     idList.add(dt.Id);
}

drugTestList = [select id, result__c from Drug_Test__c where id in :idList];

Integer i = 0;
for(Drug_Test__c dt :drugTestList){
     String resultValue = 'Positive';
     if(i%2 != 0)
        resultValue = 'Negative';

     dt.Result__c = resultValue;
     drugTestList.add(dt);
     i++;
}
test.startTest();
update drugTestList;
test.stopTest();