+ Start a Discussion
Mauricio OliveiraMauricio Oliveira 

How to obtain trigger's name within it (runtime) ?

Hi there,

I have created a class that stores trigger names to be deactivated during tests (I try to make a lot of unit tests, so I'm not interested in firing all my triggers on every test, and it is better to disable some of them to avoid reaching SOQL limits). So my tests have something like this:

TriggerDisabler.Disable('MyTriggerName');

And my triggers now add something like this as their first lines:
if (TriggerDisabler.IsTriggerDisabled('MyTriggerName')) {
    return;
}

But I would like to make this more generic, using something like a "trigger.Name" or something (without queries) that could return me the trigger's name, or eventually changing that method call in the trigger to "TriggerDisabler.AmIDisabled()" which could handle this itself.

Is this possible? I took a quick look in some forums and examples but couldn't find any way to obtain the trigger's name.

Any other suggestions are also welcome!

Cheers.
Eli Flores, SFDC DevEli Flores, SFDC Dev
Hmmm... This seems like an unwise strategy since you are cutting off processes that would run in production under the same set of circumstances.

That being said, if you use a trigger pattern that pushes all the trigger to class that handles all the triggers for a particular object, you could use static variables on the class to keep track of this.
Magdiel HerreraMagdiel Herrera
Do you know of Test.isRunningTest(),

I'm just curious on why did you wrote some thing like 

TriggerDisabler.Disable('MyTriggerName');

to be deployed to production inside a test class when you could just have

Test.isRunningTest();

inside your MyTriggerName or the code you don't want to run in test mode,

for the purpose of disabling trigger's logic in code I've always used a mixed of custom settings and static variables,

using only static variables if you ever want to enable the trigger you'll need to re-deploy the class containing the static declarations, using a mix of custom settings and static declarations you can change the settings at any time without having to deploy code.
Mauricio OliveiraMauricio Oliveira
Thank for both replies.

I don't want to disable the trigger for all my tests, just for some of them, so that is why I'm using this approach. I will try to be specific to see if I can make myself more clear:

I have a custom object representing a Payment request (my company requesting a client to pay). To create that, I need several objects to exist (Opportunity, Quote, QuoteLineItem, Product, PricebookEntry, Account, Contact). On a test, when creating the necessary environment to my custom object (all these objects I just cited) their triggers will be fired (as they should be, to ensure I am reproducing the production common process), accumulating some SOQL queries in this process. Then I create my custom object and the whole process is being tested.

But then I want another test, which is just about some instance of this custom object, to test some validation rules or field updates or something which does not affect or is affected by any of these other objects (Opportunity, Quote, etc), but since there are many lookup fields that are required to create this Payment instance, I have to create all of these referenced objects. However this consumes many SOQL queries, so there are less SOQL available for the Payment instance itself. So I created this mechanism to disable some of the triggers I don't care about when making up this whole environment which do not affect this type of test.

I'm open to other suggestions about this approach I'm using, but there is room for two questions here: 1. Should I be doing something else to test this behavior? (this is what you guys are helping me with) and 2. How can I dynamically access the name of a method/trigger being executed? (code-related question, could be applied to scenarios other than this, even if I drop this approach).

Anyway, thank you for the help so far!

Eli Flores, SFDC DevEli Flores, SFDC Dev
If you are trying to keep your setup from using too many SOQL statements during set up,  then you can

<do set up>

Test.startTest(); //this is will give you a fresh set of governor limits to work with


Test.stopTest();//everything after this will apply to original governor limits

 As far as2.  dynamically getting the name of  the method or trigger being executed, you can't as far I know. That's why you have to implement it using a class   and funnel your triggers through that, using static members to indicate to keep track of execution.
Mauricio OliveiraMauricio Oliveira
Thank you Eli, I will try to play with turning on/off test limits to reduce number of SOQL in my tests.

About my second question, I am already doing some funneling with a trigger class, but I still need to disable only part of it. For example, I have 2 different behaviors that are applied on a before update section (let's say updating some values and updating address) and I want to disable only one of them (doesn't matter if address is being updated correctly, I just care about the values in my current test). Even though I'm not using a single trigger for it but a TriggerHandler class approach, I still need to find out which method I should not execute within it. Am I being too picky to try this level of unit testing? Again, I am also doing a integration test to check that everything works as a whole, I just wanted to have some very specific tests to each functionality.

Anyway, thank you very much for the answer.


Eli Flores, SFDC DevEli Flores, SFDC Dev
My philosophy would be a little different. I'd structure it so i didn't uneccesarily update the address and structure my test so it didn't trigger the address update rather than cut it out of a unit test. Though I'm probably in a different situation, i inherited a bunch of poorly documented code so making sure everything runs during a test is how i make sure everything I know everything will run while i refactor piece by piece.

So what you would do is pretty simple to achieve. You'd add something like this to your trigger handler class

public static boolean ignoreAddressCheck {get;set;}

and then in your code that's handling trigger, you'd couch it like:

<behaviour to test>
..
if ( !(Test.isRunningTest() &&  ignoreAddressCheck) ){
<address update code>
}

Then in your testing code when you want to ignore the address update, add this line to your test method. 

TriggerHandler.ignoreAddressCheck = true;



 

Mauricio OliveiraMauricio Oliveira
Thank you once more, Eli.

Your suggestion is pretty similar to what I'm doing, but instead of using several static booleans I have a static list of strings with each one being the name of a method/trigger I should skip. This would be much better if I could make this generic as in my original question, dynamically accessing the name of the method/trigger being executed so I could have a generic condition to see if they are disabled or not. Too bad I can't do that with Apex.

I am too inheriting a bunch of poorly documented code and this is my first contact with Apex and Salesforce, so thank you a lot for your time, every opportunity to learn from more experienced people is a huge time saver.

Cheers.