+ Start a Discussion
jaanvivekjaanvivek 

Unit Testing for Apex InBound Email Service

hello All,

 

Here I'm again with some un-coverage issue for Apex In-BoundEmailService class in sfdc.

 

Here is myInbound emailservice class-

 

global class inBoundEmail implements Messaging.InboundEmailHandler
{
   global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope)
   {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
        String subToCompare = 'Create Contact';

        if(email.subject.equalsIgnoreCase(subToCompare))
        {
            Contact c = new Contact();
            c.Email=email.fromAddress;
            
            // capture phone number and city also from incoming email.
            // Splits each line by the terminating newline character  
            // and looks for the position of the phone number and city 
            String[] emailBody = email.plainTextBody.split('\n', 0);
            c.LastName=emailBody[0].substring(0);
            c.Phone = emailBody[1].substring(0);
            c.Title = emailBody[2].substring(0);
                       
            insert c;
            
            // Save attachments, if any
            if (email.textAttachments != null)
            {
            for(Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments)
            {
            Attachment attachment = new Attachment();

            attachment.Name = tAttachment.fileName;
            attachment.Body = Blob.valueOf(tAttachment.body);
            attachment.ParentId = c.Id;
            insert attachment;
            }
            
            }

            //Save any Binary Attachment
            
            if (email.binaryAttachments != null)
            {
            for(Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {
            Attachment attachment = new Attachment();

            attachment.Name = bAttachment.fileName;
            attachment.Body = bAttachment.body;
            attachment.ParentId = c.Id;
            insert attachment;
            }
           } 
        }

        result.success = true;
        return result;
             
   }
   }

Thisis the Test Class which is creating no error but it's not covering all test conditions.

 

//Test Method for main class
   
   static testMethod void TestinBoundEmail()
   {
     // create a new email and envelope object
     
   Messaging.InboundEmail email = new Messaging.InboundEmail() ;
   Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
   
   // setup the data for the email
   
  email.subject = 'Test Job Applicant';
  email.fromAddress = 'someaddress@email.com';
  
  // add an Binary attachment
  
  Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment();
  attachment.body = blob.valueOf('my attachment text');
  attachment.fileName = 'textfileone.txt';
  attachment.mimeTypeSubType = 'text/plain';
  email.binaryAttachments = new Messaging.inboundEmail.BinaryAttachment[] { attachment };
 
  // add an Text atatchment
  
  Messaging.InboundEmail.TextAttachment attachmenttext = new Messaging.InboundEmail.TextAttachment();
  attachment.body = blob.valueOf('my attachment text');
  attachment.fileName = 'textfiletwo.txt';
  attachment.mimeTypeSubType = 'texttwo/plain';
  email.textAttachments =   new Messaging.inboundEmail.TextAttachment[] { attachmenttext };
 
  // call the email service class and test it with the data in the testMethod
  inBoundEmail  testInbound=new inBoundEmail ();
  testInbound.handleInboundEmail(email, env);
    
   // create a contact data
   
    Contact testContact= new Contact();
    testContact.Email='someaddress@email.com';
    testContact.LastName='lastname';
    testContact.Phone='1234567234';
    testContact.Title='hello';
    insert testContact;
    
    system.debug('insertedcontact id===>' +testContact.Id);
   
   // Create Attachmenat data
   
  Attachment attachmnt =new Attachment();
  attachmnt.name='textfileone.txt';
  attachmnt.body =blob.valueOf('my attachment text');
  attachmnt.ParentId =testContact.Id;
  insert  attachmnt ;
   
   
   }
   

 

Could any one please make me correct in this case.

 

I tried to put all conditions and test data still it's creating problem.

 

Thanks for your valuable suggestions.

 

Thanks & regards,

jaanVivek

Best Answer chosen by Admin (Salesforce Developers) 
HariDineshHariDinesh

Hi,

 

There are 2 mistakes done by you in writing test method.

I have solved those 2 and now the below code will give 100% coverage for you.

 

Find the Main class code

 

global class inBoundEmail implements Messaging.InboundEmailHandler
{
   global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope)
   {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
        String subToCompare = 'Create Contact';

       if(email.subject.equalsIgnoreCase(subToCompare))
        {
            Contact c = new Contact();
            c.Email=email.fromAddress;
            
            // capture phone number and city also from incoming email.
            // Splits each line by the terminating newline character  
            // and looks for the position of the phone number and city 
            String[] emailBody = email.plainTextBody.split('\n', 0);
            c.LastName=emailBody[0].substring(0);
            c.Phone = emailBody[1].substring(0);
            c.Title = emailBody[2].substring(0);
                       
            insert c;
            
            // Save attachments, if any
            if (email.textAttachments != null)
            {
            for(Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments)
            {
            Attachment attachment = new Attachment();

            attachment.Name = tAttachment.fileName;
            attachment.Body = Blob.valueOf(tAttachment.body);
            attachment.ParentId = c.Id;
            insert attachment;
            }
            
            }

            //Save any Binary Attachment
            
            if (email.binaryAttachments != null)
            {
            for(Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {
            Attachment attachment = new Attachment();

            attachment.Name = bAttachment.fileName;
            attachment.Body = bAttachment.body;
            attachment.ParentId = c.Id;
            insert attachment;
            }
           } 
        }

        result.success = true;
        return result;
             
   }
}

 And the Updated Test Method

 

//Test Method for main class
   
   static testMethod void TestinBoundEmail()
   {
       // create a new email and envelope object
       Messaging.InboundEmail email = new Messaging.InboundEmail() ;
       Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
       
       // setup the data for the email
      email.subject = 'Create Contact';
      email.fromAddress = 'someaddress@email.com';
      email.plainTextBody = 'email body\n2225256325\nTitle';
      
      // add an Binary attachment
      Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment();
      attachment.body = blob.valueOf('my attachment text');
      attachment.fileName = 'textfileone.txt';
      attachment.mimeTypeSubType = 'text/plain';
      email.binaryAttachments = new Messaging.inboundEmail.BinaryAttachment[] { attachment };
      
      
  
      // add an Text atatchment
  
      Messaging.InboundEmail.TextAttachment attachmenttext = new Messaging.InboundEmail.TextAttachment();
      attachmenttext.body = 'my attachment text';
      attachmenttext.fileName = 'textfiletwo3.txt';
      attachmenttext.mimeTypeSubType = 'texttwo/plain';
      email.textAttachments =   new Messaging.inboundEmail.TextAttachment[] { attachmenttext };
      
      
      // call the email service class and test it with the data in the testMethod
      inBoundEmail  testInbound=new inBoundEmail ();
      testInbound.handleInboundEmail(email, env);
    
     
   
   }

 

Above code will give 100 coverage.

Let me know Still you face any problem.

 

 

 

 

 

All Answers

Starz26Starz26

Help us save a bit of time. what lines are not covered

jaanvivekjaanvivek

Hello,

 

Below line are not covered.

 

 Contact c = new Contact();
 11	   c.Email=email.fromAddress;
 12	  
 13	   // capture phone number and city also from incoming email.
 14	   // Splits each line by the terminating newline character
 15	   // and looks for the position of the phone number and city
 16	   String[] emailBody = email.plainTextBody.split('\n', 0);
 17	   c.LastName=emailBody[0].substring(0);
 18	   c.Phone = emailBody[1].substring(0);
 19	   c.Title = emailBody[2].substring(0);
 20	  
 21	   insert c;
 22	  
 23	   // Save attachments, if any
 24	   if (email.textAttachments != null)
 25	   {
 26	   for(Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments)
 27	   {
 28	   Attachment attachment = new Attachment();
 29	  
 30	   attachment.Name = tAttachment.fileName;
 31	   attachment.Body = Blob.valueOf(tAttachment.body);
 32	   attachment.ParentId = c.Id;
 33	   insert attachment;
 34	   }
 35	  
 36	   }
 37	  
 38	   //Save any Binary Attachment
 39	  
 40	   if (email.binaryAttachments != null)
 41	   {
 42	   for(Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {
 43	   Attachment attachment = new Attachment();
 44	  
 45	   attachment.Name = bAttachment.fileName;
 46	   attachment.Body = bAttachment.body;
 47	   attachment.ParentId = c.Id;
 48	   insert attachment;

 

 

These are the lines which are not going to covered.

 

Thanks,

JaanVivek

jaanvivekjaanvivek

Could any one suggest some points in it, I tried all but i did not get it.

 

 

Thanks,

jaanVivek

HariDineshHariDinesh

Hi,

 

There are 2 mistakes done by you in writing test method.

I have solved those 2 and now the below code will give 100% coverage for you.

 

Find the Main class code

 

global class inBoundEmail implements Messaging.InboundEmailHandler
{
   global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope)
   {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
        String subToCompare = 'Create Contact';

       if(email.subject.equalsIgnoreCase(subToCompare))
        {
            Contact c = new Contact();
            c.Email=email.fromAddress;
            
            // capture phone number and city also from incoming email.
            // Splits each line by the terminating newline character  
            // and looks for the position of the phone number and city 
            String[] emailBody = email.plainTextBody.split('\n', 0);
            c.LastName=emailBody[0].substring(0);
            c.Phone = emailBody[1].substring(0);
            c.Title = emailBody[2].substring(0);
                       
            insert c;
            
            // Save attachments, if any
            if (email.textAttachments != null)
            {
            for(Messaging.Inboundemail.TextAttachment tAttachment : email.textAttachments)
            {
            Attachment attachment = new Attachment();

            attachment.Name = tAttachment.fileName;
            attachment.Body = Blob.valueOf(tAttachment.body);
            attachment.ParentId = c.Id;
            insert attachment;
            }
            
            }

            //Save any Binary Attachment
            
            if (email.binaryAttachments != null)
            {
            for(Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {
            Attachment attachment = new Attachment();

            attachment.Name = bAttachment.fileName;
            attachment.Body = bAttachment.body;
            attachment.ParentId = c.Id;
            insert attachment;
            }
           } 
        }

        result.success = true;
        return result;
             
   }
}

 And the Updated Test Method

 

//Test Method for main class
   
   static testMethod void TestinBoundEmail()
   {
       // create a new email and envelope object
       Messaging.InboundEmail email = new Messaging.InboundEmail() ;
       Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
       
       // setup the data for the email
      email.subject = 'Create Contact';
      email.fromAddress = 'someaddress@email.com';
      email.plainTextBody = 'email body\n2225256325\nTitle';
      
      // add an Binary attachment
      Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment();
      attachment.body = blob.valueOf('my attachment text');
      attachment.fileName = 'textfileone.txt';
      attachment.mimeTypeSubType = 'text/plain';
      email.binaryAttachments = new Messaging.inboundEmail.BinaryAttachment[] { attachment };
      
      
  
      // add an Text atatchment
  
      Messaging.InboundEmail.TextAttachment attachmenttext = new Messaging.InboundEmail.TextAttachment();
      attachmenttext.body = 'my attachment text';
      attachmenttext.fileName = 'textfiletwo3.txt';
      attachmenttext.mimeTypeSubType = 'texttwo/plain';
      email.textAttachments =   new Messaging.inboundEmail.TextAttachment[] { attachmenttext };
      
      
      // call the email service class and test it with the data in the testMethod
      inBoundEmail  testInbound=new inBoundEmail ();
      testInbound.handleInboundEmail(email, env);
    
     
   
   }

 

Above code will give 100 coverage.

Let me know Still you face any problem.

 

 

 

 

 

This was selected as the best answer
jaanvivekjaanvivek

Thnx Hari.

 

I tried with below mentioned change-

 

 email.plainTextBody='email body\n2225256325\nTitle';

 

but still same problem.

 

Could you please help me what is the another change(in2 changes).

 

Why we did not insert any Contact data and Attachment data in it.

 

Suggested test class still giving 22%, code coverage.

 

static testMethod void TestinBoundEmail()
   {
     // create a new email and envelope object
     
   Messaging.InboundEmail email = new Messaging.InboundEmail() ;
   Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
   
   // setup the data for the email
   
  email.subject = 'Test Job Applicant';
  email.fromAddress = 'someaddress@email.com';
  email.plainTextBody='email body\n2225256325\nTitle';
 
  // add an Binary attachment
  Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment();
  attachment.body = blob.valueOf('my attachment text');
  attachment.fileName = 'textfileone.txt';
  attachment.mimeTypeSubType = 'text/plain';
  email.binaryAttachments = new Messaging.inboundEmail.BinaryAttachment[] { attachment };
  
  
  
 // add an Text atatchment
  
  Messaging.InboundEmail.TextAttachment attachmenttext = new Messaging.InboundEmail.TextAttachment();
  attachment.body = blob.valueOf('my attachment text');
  attachment.fileName = 'textfiletwo.txt';
  attachment.mimeTypeSubType = 'texttwo/plain';
  email.textAttachments =   new Messaging.inboundEmail.TextAttachment[] { attachmenttext };
  
 
      
  // call the email service class and test it with the data in the testMethod
  inBoundEmail  testInbound=new inBoundEmail ();
  testInbound.handleInboundEmail(email, env);
  
   
   
   }

 

 

 

 

 

Thanks & regards,

JaanVivek

HariDineshHariDinesh

Hi,

 

There is problem with the Instance of Test Attachment.

and you dont need to write creation of contact in test method.

 

Just take the Back up of your code and copy, paste my Complete Test method code.

It will solve your problem.

jaanvivekjaanvivek

Thnx, it worked fine.

 

I was also trying to write same test code but it was not giving desired results.

 

When i replaced it with your code it worked fine.

 

 

Thanks & regards,

JaanVivek

 

Jim McGrath 6Jim McGrath 6
Your test code works perfectly HariDinesh! 
ACPreveauxACPreveaux
Can someone comment on what was wrong with the code & what was fixed?  I'm trying to learn how to fish for myself here, not just get handed fish off of the internet.
kiki
Hi Hari,

Pls tell me on the test class for the below class.

Global Messaging.InboundEmailResult 
handleInboundEmail(Messaging.InboundEmail email, 
                   Messaging.InboundEnvelope env ) 
    {
    md.new_mail('target_inbound_email','target_inbound_email');
    md.debug('Started target_inbound_email');    
        
    // Create an inboundEmailResult object for returning a result
    Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
    result.Message = 'target_inbound_message';
    result.success = false;
    
    List<Attachment> a_list = new list<Attachment>();
    target_inbound__c ti = new target_inbound__c();
    
    
    
    //....
    List<Target_Inbound__c> txttoupload;
    String nameFileTxt;
    Blob contentFileTxt;
    // . . . .
    
    //....new one..
        String nameFile;
        Blob contentFile;
        String[] filelines = new String[]{};
        
        List<Target_PO__c> tptoupload;
        List<Target_Item__c> titoupload;
        List<Target_Order__C> totoupload;        
        
        List<List<String>> bol_list = new List<List<String>>();
        List<List<String>> po_list = new List<List<String>>();
        List<List<String>> my_list = new List<List<String>>();

        tptoupload = new List<Target_PO__c>();
        titoupload = new List<Target_Item__c>();
        totoupload = new List<Target_Order__c>();
        
        Target_Order__c torder = new Target_Order__c();
        Target_PO__c tpo = new target_PO__c();        
        Target_Item__c titem = new Target_Item__c();
        
    //....
        List<Target_PO__c> tptoupsert;
        List<Target_Item__c> titoupsert;
        List<Target_Order__C> totoupsert;        
        
        tptoupsert = new List<Target_PO__c>();
        titoupsert = new List<Target_Item__c>();
        totoupsert = new List<Target_Order__c>();
    //....    
        
    try {
        // get the to-address
        // note, we read this from the envelope, not the email
        // the toAddresses in the email will contain the entire list
        ti.to__c = env.toAddress;
       
        // get from address
        ti.from__c = email.fromAddress;
        //String from_name = email.fromName;
       
        // get subject line
        ti.Subject__c = email.subject;
       
        // this should relly come from email header
        // for now just use today
        ti.Sent__c = date.today();
        
        // get the email body
        ti.body__c = email.plainTextBody;
        // String body_html = email.htmlBody;
        
        insert ti;
        md.debug('==>>ID : '+ti.id);
        ID ti_id = ti.id;
        //md.debug('==>>TI_ID : '+ti_id);
        // get all the attachments, if any
        String csvbody='No attachments found';

        // . . . .
        if ( email.textAttachments != null ){
            for(Messaging.InboundEmail.TextAttachment ttt : email.textAttachments){
                md.debug('-------------------------------------------');
                md.debug('this looks like a text attachment');
                md.debug('file=' + ttt.filename);
                md.debug('\n ERROR : Attach a valid file format(.csv | .xls | .xlsx)\n');
            }
        }
        
        
        // . . . . read from file content.csv file . . . .
        
        // . . . . read from file .....
         //List...
        List<BG_Product__c> bgp = [select id from BG_Product__c where upc_code__c = '766150299885' limit 1]; 
        //List<BG_Product__c> bgp = [select id,upc_code__c from BG_Product__c]; 
        
        //...
        
        //List<Target_Order__C> tolist = new List<Target_Order__C>();
        
        if ( email.BinaryAttachments != null ){
            for(Messaging.InboundEmail.BinaryAttachment btt : email.BinaryAttachments){
            md.debug('-------------------------------------------');
            Integer count_order=1;
            Integer c=1;    
                if(btt.filename.endsWith('.csv')){
                    
                    md.debug('this looks like a binary attachment(CSV file)'); 
                    md.debug('file=' + btt.filename);
                /*    
                //attachment code too..START
                // . . . . modified code . . . .START
                    Attachment attach = new Attachment();
                    Attach.name = btt.filename;
                    // Attach.ContentType = btt.ContentType; // why does this not work?
                    Attach.body = btt.body;
                    Attach.parentid = ti.id; // id of the target_inbound object the attachment belongs to
                    a_list.add(attach.clone(false,true));
                
                            
                    contentVersion cv = new contentversion();
                    cv.versionData = btt.body;
                    cv.title = btt.filename;
                    cv.pathOnClient = btt.fileName;
                    cv.Description = 'This is a sample binary file.';
                    insert cv;
                    
                    //Adding a Content post
                    FeedItem post = new FeedItem();
                    
                    post.ParentId = ti.id; 
                    post.Body = 'This is a test post (Max Length:10,000)';
                    post.Title = 'Test_file_post';
                    
                    //post.Type = 'ContentType';
                    //post.ContentData = btt.Body ;
                    //post.ContentFileName= btt.fileName;
                    insert post;
                    
                    //create and associate a content attachment to the post
                    FeedAttachment feedAttachment = new FeedAttachment();
                    feedAttachment.FeedEntityId = post.Id;
                    feedAttachment.RecordId = cv.Id; //'***ID_OF_CONTENT_VERSION***'; 
                    //feedAttachment.Title = ttt.FileName;
                    feedAttachment.Type = 'CONTENT'; 
                    insert feedAttachment;
                //attachment code too..END
                // . . . . modified code . . . .END
                */