As per my understanding and salesforce documentation, class annotated with @isTest
should contain "only test methods". But there are some situations where we might need to have utility methods and these cannot be put in test method. For example, consider a requirement where account record has to be inserted by 2 different user profiles. Usually, I create the Account
record in the following way:
static Account createAccRec() {
Account a = new Account();
a.name = 'test';
return a;
}
and then, actual test method looks like this:
@isTest
static void createAccountasAgent1() {
user agent1 = [select id from user where profile.name = 'agent1' and isActive=true Limit 1];
system.runAs(agent1) {
insert a;
}
system.assertEquals(null, [select id from account where name='test'].Id);
}
@isTest
static void createAccountasAgent2() {
user agent1 = [select id from user where profile.name = 'agent2' and isActive=true Limit 1];
system.runAs(agent2) {
insert a;
}
system.assertNotEquals(null, [select id from account where name='test'].Id);
}
So, now this test class has 2 proper test methods and one static utility method to create data. Not sure if this will affect over all code usage but I tried to modify the non test method using @TestSetup
as follows so that now this test class has only test methods:
@testsetup
static void createAccount() {
Account a = new Account();
a.name = 'test';
}
However, using @TestSetup
followed by actual test method does not work and throws an error:
Variable does not exist : a
Is there a way to overcome this issue?
Best Answer
I disagree strongly with your assessment of how
@IsTest
annotated classes should work.As you note, you need to be able to write test utilities. For example the following is perfectly acceptable:
It could certainly be made more generic and flexible, but there's no problem with the method not being a test method.
As for coverage, the R&D team should be working on fixing this
Known Issue
: Non-test methods in a test class are counted as part of Apex code Coverage. Note, however, that@TestSetup
annotation is not a workaround, and suffers the same limitation (bug).Regardless, when you use
@TestSetup
, the only thing you can do is create records that will exist when your tests run. Static and instance variables you set in this method will not still be set when your tests run.If you would like to make it possible to have
static
variables you can set from@TestSetup
methods, vote for this Idea: Remember static variables set during testSetup annotated methods.However, it looks unlikely to be released. The last comment from the product team: