+ Start a Discussion
EdCodeEdCode 

Apex test method: create EmailMessage with Attachments

Hello,

As part of a test method, I need to create an EmailMesage (on a Case) with some Attachments.

When I performing a manual test on the UI, the functionality works fine, i.e. I simply go to a Case record and from the "Emails" Related List, I add an EmailMessage with an Attachment. During such manual process, these are the steps:
1) Adding a new Email on the Emails Related List of the Case;
2) Populate some required fields (Subject)on the email form the "To" field;
3) click the button "Attach File" > click button "Choose File" > Click button "Attach To Email" > Click button "Done".
(the Attachment is now attached to the email, even BEFORE sending that email (I guess the email record with its attachment are in a caché until the email is actually sent;
Surpringly, the EmailMessage has its standard checkbox "HasAttachment" = TRUE, even before commintting the EmailMessage record to the database.
4)  Clic button "Send" (on Email Message).

This manuall process triggers the population of a custom checkbox field "Hidden_Has_Attachment__c" on the Case object.

The problem is when coding the Apex TEST CLASS:

On the Test Class, I create the List of Cases, then the List of EmailMessages and finaly a List of Attachments.

The Attachment is associated to its parent EmailMessage through its field ParentId.

I need to create, in the Test Class, the EmailMessages WITH Attachments. How can I do this?

The TEST CLASS creates records in the following sequence:
1) Creates Case;
2) Creates EmailMessages (without Attachment)
3) Creates Attachments

The problem is: I cannot create EmailMessages WITH Attachments and insert these EmailMessages with Attachments so as to get the trigger to trigger (which would help the apex test class to pass).
The test method in the test class needs to insert EmailMessages that will enter the following if statement:
for (EmailMessage em : trigger.new){
      if (em.HasAttachment == TRUE &&
          em.ParentId.getSobjectType() == Case.SobjectType){
               emailIds.add(em.Id);
               }

When the test is done manually on the Salesforce classic UI, the Email Messages enters the if statement but when the apex test method runs, the EmailMessage is NOT entering the if statement because em.HasAttachment is NOT true.



 
Greer BanksGreer Banks
Did you ever find an answer for this?
Cristiam JacksonCristiam Jackson
I had a similar problem,  it was not possible to create the email and then assign the attachment, because the trigger would fire after the email is created and at this moment this does not have any attachment (HasAttachment = FALSE), then again when the attachment is assigned to the previously created email, this will fire a different trigger.

I used:
// Create the attachment
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();             attachment.setFileName('attachmentFilename.pdf');             attachment.setContentType('application/pdf');             attachment.setBody(Blob.valueOf('Test Body'));
// Send the email         
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();             message.setToAddresses(new List<String>{some_address});             
            message.setSubject('test');             
            message.setPlainTextBody('test');             message.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment });             message.setWhatId(SObject.Id);         
Messaging.sendEmail(new List<Messaging.Email>{message});
By this point, the trigger was fired with a new emailMessage with HasAttachment set to TRUE, however, this does not create a new Attachment record that we can use for testing purposes, if needed, then we need to add a new attachment using the Attachment object and then link this to the email, for instance:
// Query the email  
EmailMessage emailmessage = [SELECT Id, HasAttachment                                                                                         
                             FROM EmailMessage                                      
                             WHERE ToAddress =: some_address                                      
                             ORDER BY CreatedDate DESC LIMIT 1];     
// Create a custom attachment Attachment attachmentEmailMessage = new Attachment(                         ParentId = emailmessage.Id,                         
                        Body = Blob.valueOf('Test Body'),                         
                        ContentType = 'application/pdf',                         
                        Name = 'attachmentFilename.pdf');
insert attachmentEmailMessage;
A bit late, but hopefully this will be helpful for more developers.