+ Start a Discussion
prati@salesforceprati@salesforce 

Writing Test class for a trigger using attachments

Hi
I am trying to write a test class for a trigger. The trigger is on attachement object , basically the trigger has a buch of .addError statements based on some fields of parent object of attachement which is to prevent user from updating, deleting or inserting attachements to that object based on a piclist field of that object. But i am strugling here with the test class, Only 65% coverage so far.
    How should I create test data for attachment for testing purpose and I need to test for all the differnt scenarios, insert, update and delete.
Please help mw eith some examples, I can post my trigger if required.
Thank you
Best Answer chosen by prati@salesforce
Prateek Singh SengarPrateek Singh Sengar
Update Method would be something llike, please note that i dont have the structure of your custom object so you will have to create that record first
 
static testMethod void testUpdateAttachment()
{
Test.startTest();
//Custom object record insert
Blob b = Blob.valueOf('test data');
Attachment attachment = new Attachment(); 
//objectid is id of the record in which you want to create attachment, it could be a test account etc attachment.ParentId = objectId; 
attachment.Name = 'Test Attachment for Parent'; 
attachment.Body = b;   
insert(attachment);

Attachment at = [Select Id, Body, Name, ParentId from Attachment where ParentId =: objectId];
Blob b2 = Blob.valueOf('test 2 data');
at.body = b2;
update b2;
Test.stopTest();
}
Hope this helps
 

All Answers

Prateek Singh SengarPrateek Singh Sengar
Hi,
In order to create an attachment test data please use the below code. If you are facing some other difficulties please provide specific snippets where you are facing issues.
Code to create attachment data in test class
Blob b = Blob.valueOf('Test Data');
Attachment attachment = new Attachment();
//objectid is id of the record in which you want to create attachment, it could be a test account etc
attachment.ParentId = objectId;
attachment.Name = 'Test Attachment for Parent';
attachment.Body = b;
 
insert(attachment);

 
prati@salesforceprati@salesforce
Thank you for your reply... I have alredy tried using that but for my scenario, I will need to make a list of attachments. Here is my trigger,
trigger PreventDeleteRoundAttachments on Attachment (before delete, before update, before insert)
{

Schema.DescribeSObjectResult r = Round__c.sObjectType.getDescribe();
String keyPrefix = r.getKeyPrefix();

Schema.DescribeSObjectResult inv = Inventory_Exception__c.sObjectType.getDescribe();
String invKeyPrefix = inv.getKeyPrefix();

    if(trigger.isDelete)
    {

    for  (Attachment a: trigger.old)
           
        if (keyPrefix == String.ValueOf(a.ParentId).left(3) &&
            [SELECT Approval_Status__c FROM Round__c where Id =: a.ParentId].Approval_Status__c == 'Approved')
      
           {
           a.adderror('This attachment could not be deleted because the Round is complete and approved.');
           } 
        
    }
    
    if(trigger.isInsert)
    {
           
    for  (Attachment a: trigger.new)

        if (keyPrefix == String.ValueOf(a.ParentId).left(3) &&
            [SELECT Approval_Status__c FROM Round__c where Id =: a.ParentId].Approval_Status__c == 'Approved')
      
           {
           a.adderror('This attachment could not be added because the Round is complete and approved.');
           } 
           
       
           
           
    }

    if(trigger.isUpdate)
    {
           
    for  (Attachment a: trigger.new)
           
        if (keyPrefix == String.ValueOf(a.ParentId).left(3) &&
            [SELECT Approval_Status__c FROM Round__c where Id =: a.ParentId].Approval_Status__c == 'Approved')
      
           {
           a.adderror('This attachment could not be modified because the Round is complete and approved.');
           } 
           
         
    }
      

}  SO for one case I need to insert attachment first and then test for deleting it , and then I need to test for insert and update.
prati@salesforceprati@salesforce
I am able to test for the insert scenario by using try catch block but I need help with update and delete.

Thank you
Prateek Singh SengarPrateek Singh Sengar
Hi,
The same logic will work, take the following steps
  • Create 3 test methods
    • testInsertAttachment
    • testDeleteAttachment
    • testUpdateAttachment
  • In all these methods create attachment record 
  • In first method insert the dummy attachment record
  • In second method first insert the attachment then delete it
  • In third method first insert the attachment the update the content.
This should get you the required coverage. If still you are not getting the required coverage please share your test class and I can try helping with increasing the coverage. 
Prateek Singh SengarPrateek Singh Sengar
Update Method would be something llike, please note that i dont have the structure of your custom object so you will have to create that record first
 
static testMethod void testUpdateAttachment()
{
Test.startTest();
//Custom object record insert
Blob b = Blob.valueOf('test data');
Attachment attachment = new Attachment(); 
//objectid is id of the record in which you want to create attachment, it could be a test account etc attachment.ParentId = objectId; 
attachment.Name = 'Test Attachment for Parent'; 
attachment.Body = b;   
insert(attachment);

Attachment at = [Select Id, Body, Name, ParentId from Attachment where ParentId =: objectId];
Blob b2 = Blob.valueOf('test 2 data');
at.body = b2;
update b2;
Test.stopTest();
}
Hope this helps
 
This was selected as the best answer
Prateek Singh SengarPrateek Singh Sengar
sorry the query should be 
Attachment at = [Select Id, Body, Name, ParentId from Attachment where ParentId =: objectId limit 1];
prati@salesforceprati@salesforce
Thank you ... Iwill try this. But I have a question, Here we are inserting attachment in line 10 in your code but how are we making sure that it is for which parent?I am doing something like this,
I already have test data for my object,
ROund__c round = new Round__c(FY_Control__c = fycontrol.Id, Approval_Status__c = 'Submitted');
        insert round;
        Attachment attach=new Attachment();     
        attach.Name='Unit Test Attachment';
        Blob bodyBlob=Blob.valueOf('Unit Test Attachment Body');
        attach.body=bodyBlob;
        insert attach;
But how do I know this is getting inserted for this object?
Prateek Singh SengarPrateek Singh Sengar
before insert attach you get the id of the round record that you just inserted, it should be then assigned to the parentId of attachment. The code will look something like this.  

//add these two line above insert attach
String objectId = round.Id;
attach.ParentId = objectId;
prati@salesforceprati@salesforce
Thank you so much for your help but I have one small question. I created three differnt methods but do we need to create user , profile and other common data in every method or Can I do it once and then use the same?
Prateek Singh SengarPrateek Singh Sengar
yes you can, Use @tessetup annotation to create test data once and use it in all methods. For more details please refer

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_testsetup_using.htm