Sometimes when developing Apex, I've populated some static property. But then later -- most often in an Async or Test context -- I go to access it again and discover SFDC is behaving like it is accessing the property for the first time, so the value may be null, or a counter might be reset.
I don't expect static values to persist for eternity, but sometimes I find it shocking that the value no longer exists even though code is still executing.
Can anyone please explain the logic by which SFDC cleans these values? And is there anything we can do to maintain persistence a little longer?
In high-level pseudo-code, an example where this has caused a problem would be:
@IsTest
public class SomeTest {
private static final User TEST_USER = TestUserFactory.create();
@TestSetup
private static void beforeTests() {
insert TestAccountFactory.create();
}
@IsTest
private static void someTest() {
System.runAs(TEST_USER) {
// DO SOMETHING
}
// Assert someting
}
}
TestUserFactory consumes get()
in the following class to obtain what is expected to be a unique FederatedId (as well as other unique values):
@IsTest
public class XFTY_DummyDefaultValueUniqueString implements XFTY_DummyDefaultValueIntf {
private String prefix;
private static Integer counter = 1;
public XFTY_DummyDefaultValueUniqueString(String prefix) {
this.prefix = prefix;
}
public Object get() {
return this.prefix + ' ' + counter++;
}
}
However, in practice we find that running someTest() causes TestUserFactory.create(); to execute twice because of the @TestSetup method.
On the second execution, it fails because XFTY_DummyDefaultValueUniqueString.counter
is reset.
FWIW, we can make this test pass by changing the code to:
@IsTest
public class SomeTest {
private static final User TEST_USER = TestUserFactory.create();
private static final Boolean doInsert = true;
private static final Account TEST_Account = TestAccountFactory.create(doInsert);
@IsTest
private static void someTest() {
System.runAs(TEST_USER) {
// DO SOMETHING
}
// Assert someting
}
}
... which eliminates the second execution but now gives us an unused variable. (Or we could move Account creation into each test...)
... but the point is not making the test pass, but rather that XFTY_DummyDefaultValueUniqueString.counter seems to reset rather than persist.