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
Abby BeckerAbby Becker 

Help with test class failing because of field update workflow

New 'adminelope'r here - grateful for any advice that's thrown my way!

I have an Apex trigger on the Attachment sObject that changes the value of a checkbox on a related object to True when an attachment is added to the record. Below is the trigger:
 
trigger AttachmentAdded on Attachment (before insert) {	
 	
	list<Customer_Tool__c> ctListA = new List<Customer_Tool__c>();
	list<Customer_Tool__c> ctListB = new List<Customer_Tool__c>();
	Set<id> ctID = new Set<id>();

	for(Attachment at : trigger.new) {
		ctID.add(at.parentid);
	}

	ctListA = [Select id, Has_Attachment__c from Customer_Tool__c where id in: ctID];
		if(ctListA!=null && ctListA.size()>0){
			for(Customer_Tool__c ct : ctListA) {
				ct.Has_Attachment__c = true;
				ctListB.add(ct);
			}
			update ctListB;
		}
}

When the Has_Attachment__c custom field is updated to 'True,' I have a workflow rule that executes to notify another department that an attachment has been added to the record. The workflow rule also has a Field Update that "unchecks" the Has_Attachment__c field so that if ANOTHER attachment is added, they'll be notified again.

My question is how do I write a test class for this? When I deactivate the workflow rule, my test class passes. It's the workflow rule and field update that is messing it up... I just don't know how to go forward from here. Below is my test method:
 
static testMethod void testOneAttachment () {
		Customer_Tool__c ct1 = new Customer_Tool__c();
		insert ct1;

		Attachment att = new Attachment();
		Blob b = Blob.valueOf('Test Data');
		att.Name = 'Unit Test Attachment';
		att.Body = b;
		att.ParentID = ct1.Id;
		att.IsPrivate = false;
		insert att;

		List<Customer_Tool__c> cts = [select Has_Attachment__c from Customer_Tool__c where Id = :ct1.Id];

		System.assertEquals(1, cts.size());
		System.assertEquals(true, cts[0].Has_Attachment__c);  //This is failing the test because of the field update
	} //testOneAttachment

Thanks in advance
srlawr uksrlawr uk
Interesting! So if I understand you right, your problem is you can't test the "first" stage of the Workflow rule execution (ie. the notification) because in the single transaction of inserting the Attachment, your trigger sets the flag to "true" but then the second Workflow action clears the flag immediatly again! How kind of it...

Could you perhaps consider (and I know changing functionality to support testing is a bad practise ... but I am an expert in justifying bad practises...) switching over from having a check-box that is "ticked/unticked" to a numerical counter?

Then - in the trigger, instead of 
 
ct.Has_Attachment__c = true;

You would have
 
ct.Has_Attachment__c++;

and in the Workflow rule, the entry criteria, instead of checking for the boolean on Has_Attachment__c - it checks for ISCHANGED(Has_Attachment__c)

^^ Though one supposes you might change the field name too.

That way, in the test, instead of checking that the boolean was set/unset - you can check that it is now 1 instead of zero, or two instead of one (and so on).... to justify these changes I would waffle on about something like "how this also could lend itself to enhanced reporting on attachment numbers" and also that a counting system is less liable to "get stuck" or intereferre with other states...

I'll churn my mind over a little though and think if I can come up with a simple, elegant solution to just make the test a bit better too.

(I mean, technically, changing the assertion at line 16 above to be for False would be testing the end to end flow of that experience...!! Its just the transient state of the flag you are losing confirmation of!)​

 
Abby BeckerAbby Becker
Yes, srlawr, you understand me perfectly. I will churn your suggestion over a bit too, I never considered a numerical counter... I will play around and let you know if that is a workable solution.
Paul S.Paul S.
Similar to srlawr's response, what if you left the checkbox but added a datetime field for the date and time of the last attachment add and triggered your email sends based on changes to that field?