Test Class for QuickAction.QuickActionDefaultsHandler
After some thinking, I realized that I can create the instances I want by using JSON strings and deserializing them into my desireable mock implementations.
So, in my class implementing the QuickAction.QuickActionDefaultsHandler
, I did the following:
...
private QuickAction.SendEmailQuickActionDefaults GetSendEmailQuickActionFromDefaultSettings(List<QuickAction.QuickActionDefaults> defaultsSettings)
{
System.Debug(LoggingLevel.Info, JSON.serailize(defaultsSettings));
.....
From there, I looked at the output of my Debug log to get an accurate JSON string representation I could use.
It took a while of trial and error to get everything to deserialize properly, but I finally go it down to a single test.
static testmethod void DefaultCaseFeedEmailImplementor_SimpleTest()
{
//Create test data here
Exception failureDuringExecution = null;
String defaultsAsJSON = '[{"targetSObject":{"attributes":{"type":"EmailMessage"},"TextBody":"",'
+ '"FromName":"Test","FromAddress":"[email protected]","HtmlBody":"<html><body></body></html>","BccAddress":"[email protected]",'
+ '"CcAddress":"","ToAddress":"[email protected]","Subject":"Testing"},"contextId":"50011000005ZtcRAAS","actionType":"Email",'
+ '"actionName":"Case.Email","fromAddressList":["[email protected]"]}]';
List<QuickAction.SendEmailQuickActionDefaults> defaultsSettings =
(List<QuickAction.SendEmailQuickActionDefaults>)JSON.deserialize(defaultsAsJSON, List<QuickAction.SendEmailQuickActionDefaults>.class);
Test.startTest();
try { (new DefaultCaseFeedEmailImplementor()).onInitDefaults(defaultsSettings); }
catch(Exception failure) { failureDuringExecution = failure; }
Test.stopTest();
System.assertEquals(null, failureDuringExecution, 'There was an exception thrown during the test!');
//Make other assertions here
}
Now that my code can properly go over a simple test scenario, I can change my code to the following:
public with sharing class DefaultCaseFeedEmailImplementor implements QuickAction.QuickActionDefaultsHandler
{
private static final String DefaultEmailTemplateName = Label.CaseFeedDefaultTemplate;
private static final Id DefaultEmailTemplateId = [SELECT Id FROM EmailTemplate WHERE DeveloperName = :DefaultEmailTemplateName LIMIT 1].Id;
private static final String DefaultFromAddress = Label.CaseFeedDefaultFromAddress;
public void onInitDefaults(List<QuickAction.QuickActionDefaults> defaultsSettings)
{
QuickAction.SendEmailQuickActionDefaults sendEmailDefaults = GetSendEmailQuickActionFromDefaultSettings(defaultsSettings);
if(sendEmailDefaults == null) return;
EmailMessage emailMessage = (EmailMessage)sendEmailDefaults.getTargetSObject();
emailMessage.FromAddress = DefaultFromAddress;
sendEmailDefaults.setTemplateId(DefaultEmailTemplateId);
sendEmailDefaults.setInsertTemplateBody(false);
sendEmailDefaults.setIgnoreTemplateSubject(false);
}
private QuickAction.SendEmailQuickActionDefaults GetSendEmailQuickActionFromDefaultSettings(List<QuickAction.QuickActionDefaults> defaultsSettings)
{
for(QuickAction.QuickActionDefaults defaultSetting : defaultsSettings)
{
if(!(defaultSetting instanceof QuickAction.SendEmailQuickActionDefaults)) continue;
if(QuickActionIsSendEmailQuickAction((QuickAction.SendEmailQuickActionDefaults)defaultSetting))
return (QuickAction.SendEmailQuickActionDefaults)defaultSetting;
}
return null;
}
private Boolean QuickActionIsSendEmailQuickAction(QuickAction.SendEmailQuickActionDefaults actionToValidate)
{
return actionToValidate.getTargetSObject().getSObjectType() == EmailMessage.sObjectType
&& actionToValidate.getActionName().equals('Case.Email')
&& actionToValidate.getActionType().equals('Email');
}
}
Update 12/23/2015
I actually thought about it a bit more, and there is a way that is a bit easier to read.
Since I know serializedUntyped
returns a Map<String, Object>
, I can change a Map<String, Object>
into practically anything. So for this example I can do the following in my test class:
List<Map<String, Object>> defaultSettingAsUntypedObject = new List<Map<String, Object>>
{
new Map<String, Object>
{
'targetSObject' => new EmailMessage(),
'contextId' => '50011000005ZtcRAAS',
'actionType' => 'Email',
'actionName' => 'Case.Email',
'fromAddressList' => new List<String> { '[email protected]' }
}
};
List<QuickAction.SendEmailQuickActionDefaults> defaultsSettings =
(List<QuickAction.SendEmailQuickActionDefaults>)JSON.deserialize(JSON.serialize(defaultSettingAsObject), List<QuickAction.SendEmailQuickActionDefaults>.class);
It works the same way and I'm not having to guess if I messed up my JSON string or not. It is a little bit longer but much easier to read and add extra values where I need them.
In Summer'16 release Salesforce added new method which helps with testing classes implementing QuickAction.QuickActionDefaultsHandler
interface:
Test.newSendEmailQuickActionDefaults(contextId, replyToId)
So you can create records without JSON. Example:
QuickAction.SendEmailQuickActionDefaults sendEmailDefaults =
Test.newSendEmailQuickActionDefaults(case.Id, null);
Test.startTest();
CaseEmailTemplateSelector cntl = new CaseEmailTemplateSelector();
cntl.onInitDefaults(defaults);
Test.stopTest();
EmailMessage emailMessage = (EmailMessage) sendEmailDefaults.getTargetSObject();
System.assertNotEquals(null, emailMessage);
Please see Test Class Methods article in developer guide: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_test.htm