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
cashworthcashworth 

Test Method help for Inboundemail Handler

Hey developer gurus...

 

Running into a snag while trying to get coverage on an Inbound email handler. Looking to see if anyone can point me down the right path to getting a test method constructed properly so I can more this class into production. The class is "working" in sandbox perfectly but the test coverage I am getting is only 25%.

 

This class performs the following:

 

1. Receives the inbound email and dissects the envelope and email creating string variables where necessary

2. Looks up an existing account in the system and matches it to one of the toAddresses (Quote_Address__C field).

3. Looks for an existing contact where the contact's email matches the fromAddress in the envelope AND the account id from step 2.

4. Inserts a Quote Request record against the account with the contact added to that record.

5. If no contact is found, inserts a new contact on that account and then creates the quote request record.

6. Captures any attachments and adds them to the Quote Request record.

7. Sends an email back to the sender letting them know their request was received.

8. If no account is found, sends an error email back to the sender letting them know their request could not be processed.

 

I used a series of IF statements to qualify each of the 3 conditions that would come up to construct the logic behind how the email was handles and what record(s) were created. This seemed like the most reliable method to get the email handler to work 100% reliably.

 

Here's the class:

 

global class EmailQuoteRequest1 implements Messaging.InboundEmailHandler {

    public Contact vCon;
    public Account vAcc;
    public Quote_Request__c qr;
    public string toAddr;
    public string emailaddress;
    public String firstName;
    public String lastName;
    public String Subject;
    public String myPlainText;
    

 
   global Messaging.InboundEmailResult handleInboundEmail(
     Messaging.InboundEmail email,
     Messaging.InboundEnvelope envelope) {
    
         Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
         
         // Captures the sender's email address and name
         String emailAddress = envelope.fromAddress;           
         String lastName= email.fromName.substring(0,email.fromName.indexOf(' '));
         String firstName = email.fromName.substring(email.fromName.indexOf(' '));
         
         // Captures the email subject
         String Subject = email.Subject;
         
         // Add the email plain text into the local variable
         String myPlainText= '';
           myPlainText = email.plainTextBody;     
           
         //Capture the To: Addresses
         String[] toAddr = email.toAddresses; 
         
         //Check that toAddress list != null
         if (toAddr != null){          <---- I get coverage to here then nothing
         
         //Lookup Account from toAddress list
         if ([select count() from Account where Quote_Address__c in :toAddr] > 0)  {
             Account vAcc = [Select Id, OwnerId, Quote_Address__c 
             From Account
             Where Quote_Address__c in :toAddr 
             Limit 1];
             
             //Look for existing contact in the system
             if ([select count() from Contact where 
             AccountId = :vAcc.Id
             and
             Email = :envelope.fromAddress] > 0) {
                 Contact vCon = [Select Id 
                 from Contact
                 where Email = :envelope.fromAddress 
                 Limit 1];             
             
                 //Add the new Quote Request
                 Quote_Request__c[] qr = new Quote_Request__c[0];
                 qr.add(new Quote_Request__c(Request_Detail__c =  myPlainText,
                 Quote_Subject__c = Subject,
                 Customer_Contact__c = vCon.id,
                 Account__c =  vAcc.Id));
                 
                 try {                   
                   insert qr;
                   
                   //Insert Attachments if any
                     if (email.binaryAttachments != 
                     null && email.binaryAttachments.size() > 0)
                     {
                     for (integer i = 0 ; i < email.binaryAttachments.size() ; i++)
                     {
                     Attachment aB = new Attachment(ParentId = qr[0].Id,
                     Name = email.binaryAttachments[i].filename,
                     Body = email.binaryAttachments[i].body);
                     insert aB;
                     }
                     }
         
                     if (email.textAttachments != 
                     null && email.textAttachments.size() > 0)
                     {
                     for (integer i = 0 ; i < email.textAttachments.size() ; i++)
                     {
                     Attachment aT = new Attachment(ParentId = qr[0].Id,
                     Name = email.textAttachments[i].filename,
                     Body = Blob.valueOf(email.textAttachments[i].body));
                     insert aT;
                     }
                     }
                   
                   } catch (System.DmlException e)
                   { result.success = false;
                     result.message = 'failed to attach to account.';
                   System.debug('ERROR: Not able to create Quote Request: ' + e);
                 } 
                 
                     // Send return email to sender confirming receipt of request
                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                     mail.setToAddresses( new String[] { emailAddress });
                     mail.setSubject('Your quote request has been received');
                     mail.setPlainTextBody('Thank you for submitting your request. { existing contact }. Your Account Manager will be in touch shortly to discuss the details of your request.');
                     Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); 
                     
                 
 

Best Answer chosen by Admin (Salesforce Developers) 
cashworthcashworth

I managed to figure out what it was I was doing wrong here and now have 100% coverage. It had to do with the way I defined the toAddress in the test email. Ended up needing to define a List String{] first and then reference the viable in the email.toAdddresses field when creating the test message.

All Answers

cashworthcashworth
            }  else {  
             
             //Insert new conact
             Contact vCon = new Contact();
             vCon.FirstName = firstname;
             vCon.LastName = lastname;
             vCon.email = emailaddress;
             vCon.Accountid = vAcc.id;
             vCon.OwnerId = vAcc.OwnerId;
             insert vCon;
             
                 //Add the new Quote Request
                 Quote_Request__c[] qr = new Quote_Request__c[0];
                 qr.add(new Quote_Request__c(Request_Detail__c =  myPlainText,
                 Quote_Subject__c = Subject,
                 Customer_Contact__c = vCon.id,
                 Account__c =  vAcc.Id));
                 
                 try {                   
                   insert qr;
                   
                   
                 //Insert Attachments if any
                     if (email.binaryAttachments != 
                     null && email.binaryAttachments.size() > 0)
                     {
                     for (integer i = 0 ; i < email.binaryAttachments.size() ; i++)
                     {
                     Attachment aB = new Attachment(ParentId = qr[0].Id,
                     Name = email.binaryAttachments[i].filename,
                     Body = email.binaryAttachments[i].body);
                     insert aB;
                     }
                     }
         
                     if (email.textAttachments != 
                     null && email.textAttachments.size() > 0)
                     {
                     for (integer i = 0 ; i < email.textAttachments.size() ; i++)
                     {
                     Attachment aT = new Attachment(ParentId = qr[0].Id,
                     Name = email.textAttachments[i].filename,
                     Body = Blob.valueOf(email.textAttachments[i].body));
                     insert aT;
                     }
                     }
                   
                   } catch (System.DmlException e)
                   {result.success = false;
                    result.message = 'failed to add contact.'; 
                    System.debug('ERROR: Not able to create Quote Request: ' + e);
                 } 
                 
                     
                     // Send return email to sender confirming receipt of request
                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                     mail.setToAddresses( new String[] { emailAddress });
                     mail.setSubject('Your quote request has been received');
                     mail.setPlainTextBody('Thank you for submitting your request. { new contact }. Your Account Manager will be in touch shortly to discuss the details of your request.');
                     Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); 
                                  
             }
            
            } else {
         
         //Throw exception and return email to sender  
         Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
         mail.setToAddresses( new String[] { emailAddress });
         mail.setSubject('Your quote request could not be processed');
         mail.setPlainTextBody('Thank you for submitting your request. Unfortunately the request could not be processed by the system. Please contact your Account Manager directly for assitance in submitting your request.');
         Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
       
      }
            
            
            
                 
         } else {
         
         //Throw exception and return email to sender  
         Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
         mail.setToAddresses( new String[] { emailAddress });
         mail.setSubject('Your quote request could not be processed');
         mail.setPlainTextBody('Thank you for submitting your request. Unfortunately the request could not be processed by the system. Please contact your Account Manager directly for assitance in submitting your request.');
         Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
       
      }        
      
   return result;  
     
 } 
  
Here is the test method that is only giving partial coverage.

 


 static testmethod void testemailquoteexistingcontact() {
 
Id aId;
Id cTId;
Id qId;
 
 // Create a new email and envelope object
  Messaging.InboundEmail email = new Messaging.InboundEmail();
  Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
 
  // Create the plainTextBody and fromAddres for the test
  email.plainTextBody = 'Test Method Email';
  env.fromAddress = 'xxxxx@gmail.com';
  env.toAddress = 'quoterequests@xxxxxx.net';
  email.subject = 'testmethod email';
  email.fromName = 'Some Name';
  
  //create an attachment
  Messaging.InboundEmail.TextAttachment inbTextAttchment = new Messaging.InboundEmail.TextAttachment();
  inbTextAttchment.body = 'Test Test Test Test Test Test Test Test Test';
  inbTextAttchment.fileName = 'myAttachment.txt';
  Messaging.InboundEmail.TextAttachment[] textAttachs = new Messaging.InboundEmail.TextAttachment[1];
  textAttachs[0] = inbTextAttchment;   
  email.textAttachments = textAttachs; 
  
  //create an account
  Account a = new Account();
   a.name = 'AName';
   a.type = 'Prospect';
   a.Quote_Address__c = 'quoterequests@xxxxxxx.net';
   Database.insert(a);
   aId = a.Id;
   
  //create an contact
   Contact cT = new Contact();
    cT.firstname = 'AName';
    cT.lastname = 'Prospect';
    cT.email = 'someaddress@email.com';
    cT.AccountId = aId;
    Database.insert(cT);
    cTId = cT.Id; 
  
 
 EmailQuoteRequest1 eqr = new EmailQuoteRequest1();
 eqr.handleInboundEmail(email, env );           
                
  } 
Any thoughts on how to get the coverage past the first IF statement would be appreciated.
TrueCloudTrueCloud

This may sound ridiculous but I had a similar issue when I was working with InBound Email Handler. It is hard to simulate and write a test class for all the code especially with Attachments and creating emailMessages. The way was able to overcome the coverage issue was by creating useless methods that were never going to be true for my business case. Eventually I added some additional code that got executed during my test only, which brought the overall coverage to be more than 75%:).

 

Hope this helps.

cashworthcashworth

Thanks for the suggestion and I don't think it sounds ridiculous at all. I do have 2 more things I am working on doing in terms of restructuring the class so I can get some coverage but this will be a good fall-back position if I get in a pinch and have to deploy to production early.

 

Thx,

Clay

cashworthcashworth

I managed to figure out what it was I was doing wrong here and now have 100% coverage. It had to do with the way I defined the toAddress in the test email. Ended up needing to define a List String{] first and then reference the viable in the email.toAdddresses field when creating the test message.

This was selected as the best answer
Rasmus MenckeRasmus Mencke

Here is a link to some sample code which includes test methods, I have posted several samples on the site

http://wiki.developerforce.com/index.php/Force.com_Email_Services