You need to sign in to do that
Don't have an account?
ChrisSargent
Unit Test Help (My first Apex class and Test)
Hello,
I'm writing a simple Apex class that will change the field of a contact when an email is sent to a BCC salesforce email services address. I've written the class in my Sandbox and it all seems to be working fine so I now need to test it to I can deploy it to my production environment. I've written a test as far as I can so far and I'm getting no errors, with 50% code coverage.
I'm not quite sure what else I need to test to be able to get to 100% code coverage; any help would therefore be much appreciated.
Here's my Class:
And my test class:
Thanks in advance!
Chris
I'm writing a simple Apex class that will change the field of a contact when an email is sent to a BCC salesforce email services address. I've written the class in my Sandbox and it all seems to be working fine so I now need to test it to I can deploy it to my production environment. I've written a test as far as I can so far and I'm getting no errors, with 50% code coverage.
I'm not quite sure what else I need to test to be able to get to 100% code coverage; any help would therefore be much appreciated.
Here's my Class:
global class UpdateToutAppStage implements Messaging.InboundEmailHandler { global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope env){ // Create an InboundEmailResult object for returning the result of the Apex Email Service Messaging.InboundEmailResult result = new Messaging.InboundEmailResult(); String emailSubject = email.Subject; String [] emailToList = email.toAddresses; String newStage = null; String toEmail = null; // Run a for loop through the "email to" list, in case of sending to multiple people. for(Integer i = 0; i < emailToList.size(); i++){ toEmail = emailToList[i]; // Try to look up any contacts based on the email to address // If there is more than one contact with the same email address, an exception will be thrown and the catch statement will be called. try { Contact vCon = [SELECT Id, Name, Email FROM Contact WHERE Email = :toEmail LIMIT 1]; // Check the Email Subject and Adjust the newStage variable accordingly. if (emailSubject == 'Congratulations on your recent funding' || emailSubject == 'Hiring awesome people for amazing companies'){ newStage = 'Stage 1'; } else if (emailSubject == 'Re: Congratulations on your recent funding' || emailSubject == 'Re: Hiring awesome people for amazing companies'){ newStage = 'Stage 2'; } else if (emailSubject == 'Trying to connect'){ newStage = 'Stage 3'; } else if (emailSubject.contains('take this thing offline?')){ newStage = 'Stage 4'; } else if (emailSubject.contains('Am I not getting the hint?')){ newStage = 'Completed'; } else { newStage = 'Undefined'; } // Set the field to be equal to the variable string vCon.Marketing_Campaign__c = newStage; // Update the Contact record update vCon; // Writes a note to the the debugging log System.debug('ToutApp Stage Field Updated To: ' + newStage ); } // If an exception occurs when the query accesses the contact record, a QueryException is called. The exception is written to the Apex debug log. catch (QueryException e) { System.debug('ToutApp Stage Failed: ' + e); } } // End the For loop // Set the result to true. No need to send an email back to the user with an error message result.success = true; // Return the result for the Apex Email Service return result; } }
And my test class:
@isTest private class TestUpdateToutAppStage { static testMethod void TestUpdateToutApp() { // 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 = 'Congratulations on your recent funding'; String[] toAddresses = new String[] {'me@email1.com','you@email2.com'}; email.toAddresses = toAddresses; // call the ToutApp class and test it with the data in the testMethod UpdateToutAppStage testInbound = new UpdateToutAppStage (); testInbound.handleInboundEmail(email, env); } }
Thanks in advance!
Chris
Also, not related to testing, you may consider using emailSubject.contains() instead of emailSubject == in all of your if else statements. It may not be an issue because maybe the emails coming in are generated by a system and will always have a consistently worded subject but it will only take one character added to a subject line for a email to not hit the first 3 if else statements
Thanks for your answer. I tried writing several test methods, basically duplicating the above code and testing with several different subject lines - covering 4 of the if statements and one that would hit the else statement. I stuck at 50% code coverage.
So then I turned my attention to checking the status was being updated so I changed the test method to this:
Again, the tests pass but I'm still stuck at 50%. I suspect that the final 'if' statement is not being fired though because I don't think the SOQL query is returning a result, even though there is a record with the *****@btinternet.com email address (edited for privacy!). Also, before I put the if statement in, I was getting an out of bounds error.
I take your point on the subjects having to match but they are system generated and I could use contains for the first one as the second email is a reply which will contain it. Probably better for me to have seperate classes firing from different email addresses but I can look at that later.
Any other thoughts or pointers please?
Chris
Apex Class:
The test class:
The query should be [SELECT Id FROM Contact WHERE Email IN :emailToList]
Thanks for the answer. I changed my strategy slightly and set up different Inbound Mail addresses for each of the different stages. Then I have seperate inbound handler apex classes for each email address (because it's always BCC'd there's no other way of seeing which email it was sent to) which then call a single Apex class passing the New Stage in a variable, which then updates the stage on the record.
Made my testing fairly simple as there were way less if then else statements etc. I don't think my test is that efficient at the moment, I can probably change it to a for loop. For reference, here's my new code.
One of the inbound mail handlers:
The Updating Stage Apex Class:
And the Test Class (as I said, I can probably put the individual tests in a for loop but just haven't got round to it.
I must have learnt something because I wrote a Trigger and a class later in the day, then wrote my test code which passed with 100% on the 2nd attempt!
Thanks for the help.