You need to sign in to do that
Don't have an account?
Scott Brady
Inbound Email Handler - Test Class Issues
Hi All,
I have the following, basic, inbound email handler class:
The class works just fine for me, however, when I am trying to create a test class, I keep receiving nullpoint exceptions - it's always line 24
I have two questions:
1. Why am I receiving that error when I believe that variable is defined above on the previous line.
2. I am not the best with test classes, so I know that this will not test ALL of my class and I will need to add to it - however would this test class point me in the right direction? Or do I need to change quite a bit?
Any assistance that could be provided would be wonderful, I am still learning a bit about the test classes/requirements as I go.
I have the following, basic, inbound email handler class:
global class ProcessInboundEmailSupport implements Messaging.InboundEmailHandler { global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) { Messaging.InboundEmailResult result = new Messaging.InboundEmailresult(); BMCServiceDesk__Incident__c ticket = new BMCServiceDesk__Incident__c(); if([select count() from Account where Account.Support_Email_Service__c = :email.toAddresses] == 0) { } else { ticket.BMCServiceDesk__FKAccount__c = [select Id from Account where Account.Support_Email_Service__c = :email.toAddresses].Id; ticket.BMCServiceDesk__shortDescription__c = email.subject; ticket.BMCServiceDesk__incidentDescription__c = email.plaintextbody; ticket.BMCServiceDesk__FKContact__c = [select Id from Contact where contact.Email = :email.fromAddress].Id; ticket.Source__c = 'Email'; ticket.BMCServiceDesk__FKCategory__c = 'a2kS0000000lg1Q'; ticket.Emailed_From__c = email.fromAddress; } insert ticket; System.debug('====> Created ticket '+ticket.Id); BMCServiceDesk__IncidentHistory__c action = new BMCServiceDesk__IncidentHistory__c(); action.BMCServiceDesk__FKAction__c = 'a0QS0000003wjRR'; action.BMCServiceDesk__note__c = 'From:' +' '+ email.fromAddress +'\n'+ 'To:' +' '+ email.toAddresses +'\n'+ 'Cc:' +' '+ email.ccAddresses +'\n'+ 'Subject:' +' '+ email.subject +'\n'+ 'Body:' +' '+ email.plaintextbody; action.BMCServiceDesk__FKIncident__c = ticket.id; insert action; if (email.binaryAttachments != null && email.binaryAttachments.size() > 0) { for (integer i = 0 ; i < email.binaryAttachments.size() ; i++) { Attachment attachment = new Attachment(); attachment.ParentId = ticket.Id; attachment.Name = email.binaryAttachments[i].filename; attachment.Body = email.binaryAttachments[i].body; insert attachment; } } return result; } }
The class works just fine for me, however, when I am trying to create a test class, I keep receiving nullpoint exceptions - it's always line 24
@isTest public class TestSupportHandler { public static testMethod void TestMyController() { // 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 Email Subject'; env.fromAddress = 'sbrady@digitalhands.com'; // add an attachment Messaging.InboundEmail.BinaryAttachment attachment = new Messaging.InboundEmail.BinaryAttachment(); attachment.body = blob.valueOf('my attachment text'); attachment.fileName = 'textfile.txt'; attachment.mimeTypeSubType = 'text/plain'; email.binaryAttachments = new Messaging.inboundEmail.BinaryAttachment[] { attachment }; // call the email service class and test it with the data in the testMethod ProcessInboundEmailSupport emailProcess = new ProcessInboundEmailSupport(); emailProcess.handleInboundEmail(email, env); // query for the ticket the email service created BMCServiceDesk__Incident__c ticket = [select id, Emailed_From__c from BMCServiceDesk__Incident__c where Emailed_From__c = :env.fromAddress]; System.assertEquals(ticket.Emailed_From__c,'sbrady@digitalhands.com'); // find the attachment Attachment a = [select name from attachment where parentId = :ticket.id]; System.assertEquals(a.name,'textfile.txt'); } }
I have two questions:
1. Why am I receiving that error when I believe that variable is defined above on the previous line.
2. I am not the best with test classes, so I know that this will not test ALL of my class and I will need to add to it - however would this test class point me in the right direction? Or do I need to change quite a bit?
Any assistance that could be provided would be wonderful, I am still learning a bit about the test classes/requirements as I go.
"I'm now at 72% code coverage and just need to add my other steps from the original class (category etc)."
create an account with its required fields and at least Support_Email_Service__c = email.toAddresses
A good practice is to use a test setup method but it is not mandatory.
Account acc = new Account(name='xxx', Support_Email_Service__c = '<email to addresses value >', ... );
insert acc;
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_testsetup_using.htm
Regards
All Answers
You have used hardcoded IDs. You will need to use @isTest (SeeAllData=true)
ticket.BMCServiceDesk__FKCategory__c = 'a2kS0000000lg1Q'; // without any account this one is not used.
action.BMCServiceDesk__FKAction__c = 'a0QS0000003wjRR';
insert action; // should fail because the BMCServiceDesk__FKAction__c doesn't exist.
Regards
I'm still confused. I understand the change for SeeAllData, but i'm still getting
System.NullPointerException: Attempt to de-reference a null object
External entry point Class.TestSupportHandler.TestMyController: line 24, column 1
Is that pointing to the email itself? That's the part that is tripping me up. I know how to test to make sure the handler did the correct assignments to the resulting ticket that will be created from the email, but I can't even get the test class to run because of the error above. I do understand that if the account is not found, the handler should fail - are you telling me to add the category/insert action code to the test class as well?
Is the null object being referenced the ticket that it's trying to create when the email is sent through the test?
We still need to investigate this.
Your code is very close to the sample of a testing class of Salesforce:
https://help.salesforce.com/articleView?id=code_inbound_email.htm&type=0
Launching the test with the Developer Console (open your testing class and click on the button "Run Test" (top, left)) and looking at the Logs (tab, bottom left) for the result of the system.debug added above.
Regards.
The problem occurs first at the line [9] : System.NullPointerException: Attempt to de-reference a null object
so the problem is here: if([select count() from Account where Account.Support_Email_Service__c = :email.toAddresses] == 0) {
email.toAddresses is a list of String.
Just add the line below in bold:
// setup the data for the email
email.subject = 'Test Email Subject';
email.toAddresses = new List<String>{'titi@test.com'};
env.fromAddress = 'sbrady@digitalhands.com';
There is still the problem of the hardcoded Ids (even with @isTest (SeeAllData=true).
Your test could work in the sandbox org now but it could fail in production. You should try to get these Ids with two requests SOQL using the name or external Ids (keys as string) of the targetted objects.
Regards
Alain
I have also updated the harcoded ID's with queries for the name (which is the same in prod as in sandbox). Thanks for the tips.
In that case, would i be able to remove the seealldata tag?
"I'm now at 72% code coverage and just need to add my other steps from the original class (category etc)."
create an account with its required fields and at least Support_Email_Service__c = email.toAddresses
A good practice is to use a test setup method but it is not mandatory.
Account acc = new Account(name='xxx', Support_Email_Service__c = '<email to addresses value >', ... );
insert acc;
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_testsetup_using.htm
Regards
Answered.