Closed ctcforce closed 7 months ago
There are two solution to this:
1) Do not perform DML to test your trigger logic - see https://github.com/mitchspano/apex-trigger-actions-framework?tab=readme-ov-file#dml-less-trigger-testing
2) Inject the Trigger_Action__mdt
rows you want into execute into MetadataTriggerHandler
during test execution:
https://github.com/mitchspano/apex-trigger-actions-framework/blob/main/trigger-actions-framework/main/default/classes/MetadataTriggerHandler.cls#L339
Generally speaking - this is not an issue with the framework, but a structural change which to the way unit tests are to be written in your org.
The system is working as intended, so I am closing this issue.
Those are both fair points. I've been taking for granted that live custom metadata records are freely available in a test context. I'll pivot to explicitly creating/updating the custom metadata records that my logic relies upon.
Thanks for the quick response!
I attempted to explicitly set the afterInsertActionMetadata
per the second link you provided
@TestSetup
private static void setup() {
sObject_Trigger_Setting__mdt sobjectMDT;
try{
sobjectMDT = [SELECT Bypass_Execution__c FROM sObject_Trigger_Setting__mdt WHERE Object_API_Name__c = 'ContentDocumentLink'];
if(sobjectMDT.Bypass_Execution__c != false){
sobjectMDT.Bypass_Execution__c = false;
}
} catch (Exception e){
sobjectMDT = new sObject_Trigger_Setting__mdt(Object_API_Name__c='ContentDocumentLink', Bypass_Execution__c = false);
}
Trigger_Action__mdt triggerActionMDT;
try{
triggerActionMDT = [ SELECT Bypass_Execution__c FROM Trigger_Action__mdt WHERE Apex_Class_Name__c = 'TA_ContentDocumentLink_ReopenCase' AND After_Insert__c = :sobjectMDT.Id];
if(triggerActionMDT.Bypass_Execution__c != false){
triggerActionMDT.Bypass_Execution__c = false;
}
} catch (Exception e){
triggerActionMDT = new Trigger_Action__mdt(Apex_Class_Name__c = 'TA_ContentDocumentLink_ReopenCase', After_Insert__c = sobjectMDT.Id, Bypass_Execution__c = false);
}
MetadataTriggerHandler.afterInsertActionMetadata = new List<Trigger_Action__mdt>{triggerActionMDT};
}
But I got this deployment error Variable does not exist: afterInsertActionMetadata
presumably because the set
accessor doesn't have an explicit implementation.
I also tried the following, both in the setup and directly in the test method and still the action is bypassed.
private static void setup() {
MetadataTriggerHandler.clearBypass('ContentDocumentLink');
MetadataTriggerHandler.clearBypass('ReopenCaseUponFileUpload');
}
I must not entirely grok your second point above. What is the recommended approach to inject these MDT records?
This can be accomplished without any modifications to the framework by leveraging the fact that the inner MetadataTriggerHandler.Selector
is @TestVisible
and virtual
:
@TestVisible
private virtual inherited sharing class Selector {
public virtual List<SObject> query(String queryString) {
return Database.query(queryString);
}
}
So in a test class, you can override this and mutate the query results however you like:
@IsTest
private class SomeTest {
@IsTest
private static void fooShouldBar() {
MetadataTriggerHandler.selector = new SomeTest.FakeSelector();
insert new Account(Name = 'Acme'); // _all_ trigger actions will execute now, regardless of `Bypass_Execution__c` value
}
private class FakeSelector extends MetadataTriggerHandler.Selector {
public override List<SObject> query(String queryString) {
String queryStringWithoutBypassCheck = queryString.replace('AND Bypass_Execution__c = FALSE', '');
List<SObject> allTriggerActionsForThisContext = Database.query(queryStringWithoutBypassCheck);
// mutate further if you like - perhaps setting `Bypass_Permission__c` or `Required_Permission__c` as needed
return allTriggerActionsForThisContext;
}
}
}
Expected Behavior
When an
sObject_Trigger_Setting__mdt
orTrigger_Action__mdt
hasBypass_Execution__c
==TRUE
, during execution of apex test class methods, TAF should execute the configured Trigger Action anyways.Actual Behavior
Apex test methods that rely on TAF executing a configured trigger action fail when a global bypass is set in the MDT.
Steps to Reproduce the Problem
Specifications