How is it possible for @TestSetup to effect test result?
Clash Royale CLAN TAG#URR8PPP
While refactoring a test to make it more consistent with the style of our other tests, a colleague came upon something really weird.
The original test created the test account in @TestSetup, like so:
@IsTest
public TestClass2
private static final Boolean doInsert = true;
@TestSetup
public static void beforeTest()
TestAccountFactory.create(doInsert);
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = [SELECT Id FROM Account LIMIT 1];
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
As noted, the assertions pass.
In the modified form, the test created the Account within the test, like so:
@IsTest
public TestClass1
private static final Boolean doInsert = true;
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = TestAccountFactory.create(doInsert);
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Fails
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Now, the second assertion fails even though the only difference is that the Account was not created in @TestSetup.
This is obviously a simplification of the code and our path to discovering this discrepancy was a torturous one, but we are trying to understand how this difference would even be possible and whether this is something that we could have expected or reflects a defect in how SFDC is executing the test?
apex unit-test failing-tests test-setup inconsistent
add a comment |
While refactoring a test to make it more consistent with the style of our other tests, a colleague came upon something really weird.
The original test created the test account in @TestSetup, like so:
@IsTest
public TestClass2
private static final Boolean doInsert = true;
@TestSetup
public static void beforeTest()
TestAccountFactory.create(doInsert);
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = [SELECT Id FROM Account LIMIT 1];
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
As noted, the assertions pass.
In the modified form, the test created the Account within the test, like so:
@IsTest
public TestClass1
private static final Boolean doInsert = true;
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = TestAccountFactory.create(doInsert);
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Fails
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Now, the second assertion fails even though the only difference is that the Account was not created in @TestSetup.
This is obviously a simplification of the code and our path to discovering this discrepancy was a torturous one, but we are trying to understand how this difference would even be possible and whether this is something that we could have expected or reflects a defect in how SFDC is executing the test?
apex unit-test failing-tests test-setup inconsistent
This code would not compile. Your first example referencesdoInsert
out of scope.
– Adrian Larson♦
Feb 16 at 17:51
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54
add a comment |
While refactoring a test to make it more consistent with the style of our other tests, a colleague came upon something really weird.
The original test created the test account in @TestSetup, like so:
@IsTest
public TestClass2
private static final Boolean doInsert = true;
@TestSetup
public static void beforeTest()
TestAccountFactory.create(doInsert);
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = [SELECT Id FROM Account LIMIT 1];
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
As noted, the assertions pass.
In the modified form, the test created the Account within the test, like so:
@IsTest
public TestClass1
private static final Boolean doInsert = true;
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = TestAccountFactory.create(doInsert);
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Fails
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Now, the second assertion fails even though the only difference is that the Account was not created in @TestSetup.
This is obviously a simplification of the code and our path to discovering this discrepancy was a torturous one, but we are trying to understand how this difference would even be possible and whether this is something that we could have expected or reflects a defect in how SFDC is executing the test?
apex unit-test failing-tests test-setup inconsistent
While refactoring a test to make it more consistent with the style of our other tests, a colleague came upon something really weird.
The original test created the test account in @TestSetup, like so:
@IsTest
public TestClass2
private static final Boolean doInsert = true;
@TestSetup
public static void beforeTest()
TestAccountFactory.create(doInsert);
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = [SELECT Id FROM Account LIMIT 1];
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
As noted, the assertions pass.
In the modified form, the test created the Account within the test, like so:
@IsTest
public TestClass1
private static final Boolean doInsert = true;
@IsTest
public static void testSomething()
User testUser = TestUserFactory.create(doInsert);
Account testAccount = TestAccountFactory.create(doInsert);
String expectedStatus = 'Active';
System.runAs(testUser)
Test.startTest();
SpagettiCode.abandonAllHopeAllYeWhoEnterHere();
// Passes
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Test.stopTest();
// Fails
System.assertEquals(
expectedStatus,
[SELECT Status__c FROM Account
WHERE Id = :testAccount.Id].Status__c]
);
Now, the second assertion fails even though the only difference is that the Account was not created in @TestSetup.
This is obviously a simplification of the code and our path to discovering this discrepancy was a torturous one, but we are trying to understand how this difference would even be possible and whether this is something that we could have expected or reflects a defect in how SFDC is executing the test?
apex unit-test failing-tests test-setup inconsistent
apex unit-test failing-tests test-setup inconsistent
edited Feb 16 at 17:55
Brian Kessler
asked Feb 16 at 17:47
Brian KesslerBrian Kessler
1,6411132
1,6411132
This code would not compile. Your first example referencesdoInsert
out of scope.
– Adrian Larson♦
Feb 16 at 17:51
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54
add a comment |
This code would not compile. Your first example referencesdoInsert
out of scope.
– Adrian Larson♦
Feb 16 at 17:51
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54
This code would not compile. Your first example references
doInsert
out of scope.– Adrian Larson♦
Feb 16 at 17:51
This code would not compile. Your first example references
doInsert
out of scope.– Adrian Larson♦
Feb 16 at 17:51
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54
add a comment |
2 Answers
2
active
oldest
votes
Side effects in your test data factory, in automation fired on Account insert, or interactions between those entities and your code under test can absolutely cause this kind of behavior change.
@testSetup
executes in a mostly-isolated transaction, insulating you from many of the potential side effects and code interactions between your setup process and your actual code under test. Removing that barrier opens a wide range of potential sources of interference, such as static variables that are not reset after test initialization, limits that have already been partially consumed, enqueued asynchronous actions, possible Mixed DML traps, and so on.
I would find this behavior somewhat surprising but not unheard-of while working with legacy or poorly-architected code, as it sounds like you are here.
One specific example where you can get this kind of weirdness is low-quality trigger recursion guards based on static Booleans (people often call them something like runOnce
). Insert the Account, the trigger runs once. Do something else with the Account.... the trigger doesn't run again, because you're still in the same transaction and the static didn't get reset.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
This is being caused by a "recursion blocker" (as mentioned by David Reed). The fix is to remove or correct the recursion blocker from your trigger logic. The reason why this happened is because static variables are reset between unit tests and test setup methods; as long as the trigger ran during test setup, it would have been reset for the unit tests. When the account is created within the unit test itself, the static variable is not reset, causing the behavior you see here.
To fix the problem, first try commenting out the recursion blocker logic and run some tests to make sure nothing breaks. If you get a "record is already in trigger" or "trigger depth exceeded" error, you'll need the recursion blocker, but you should modify it so it resets itself intelligently, or write "rising edge" trigger logic.
Here's my preferred form of recursion blocking:
static Boolean runOnce = false;
public static void beforeInsert(sObject records)
if(runOnce)
return;
runOnce = true;
doBeforeInsertLogicWith(records);
runOnce = false;
The secret sauce is the last line; by resetting the variable when the trigger contexts concludes, you'll fix the unit test problem and also allow the trigger to run correctly with batches of records larger than 200.
For rising edge triggers, you check to make sure the record will meet the condition, instead of checking if it already meets the condition.
Here's an example of this:
public static Boolean checkTransition(sobject oldRecord, sobject newRecord)
return oldRecord.get(someField) != newRecord.get(someField);
public static void handleRecords(sobject oldRecords, sobject newRecords)
sobject updates = new sobject[0];
for(Integer i = 0, s = newRecords.size(); i < s; i++)
if(checkTransition(oldRecords[i], newRecords[i]))
updates.add(newRecords[i]);
if(!updates.isEmpty())
doUpdatesOn(updates);
Obviously, these are meant more as pseudo-code, but hopefully you should be able to get to a fix using these ideas. Make sure you have a trigger unit test, and attempt to perform logic on at least 201 records in a single list, just to make sure that it is working appropriately either way.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "459"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f250582%2fhow-is-it-possible-for-testsetup-to-effect-test-result%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Side effects in your test data factory, in automation fired on Account insert, or interactions between those entities and your code under test can absolutely cause this kind of behavior change.
@testSetup
executes in a mostly-isolated transaction, insulating you from many of the potential side effects and code interactions between your setup process and your actual code under test. Removing that barrier opens a wide range of potential sources of interference, such as static variables that are not reset after test initialization, limits that have already been partially consumed, enqueued asynchronous actions, possible Mixed DML traps, and so on.
I would find this behavior somewhat surprising but not unheard-of while working with legacy or poorly-architected code, as it sounds like you are here.
One specific example where you can get this kind of weirdness is low-quality trigger recursion guards based on static Booleans (people often call them something like runOnce
). Insert the Account, the trigger runs once. Do something else with the Account.... the trigger doesn't run again, because you're still in the same transaction and the static didn't get reset.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Side effects in your test data factory, in automation fired on Account insert, or interactions between those entities and your code under test can absolutely cause this kind of behavior change.
@testSetup
executes in a mostly-isolated transaction, insulating you from many of the potential side effects and code interactions between your setup process and your actual code under test. Removing that barrier opens a wide range of potential sources of interference, such as static variables that are not reset after test initialization, limits that have already been partially consumed, enqueued asynchronous actions, possible Mixed DML traps, and so on.
I would find this behavior somewhat surprising but not unheard-of while working with legacy or poorly-architected code, as it sounds like you are here.
One specific example where you can get this kind of weirdness is low-quality trigger recursion guards based on static Booleans (people often call them something like runOnce
). Insert the Account, the trigger runs once. Do something else with the Account.... the trigger doesn't run again, because you're still in the same transaction and the static didn't get reset.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Side effects in your test data factory, in automation fired on Account insert, or interactions between those entities and your code under test can absolutely cause this kind of behavior change.
@testSetup
executes in a mostly-isolated transaction, insulating you from many of the potential side effects and code interactions between your setup process and your actual code under test. Removing that barrier opens a wide range of potential sources of interference, such as static variables that are not reset after test initialization, limits that have already been partially consumed, enqueued asynchronous actions, possible Mixed DML traps, and so on.
I would find this behavior somewhat surprising but not unheard-of while working with legacy or poorly-architected code, as it sounds like you are here.
One specific example where you can get this kind of weirdness is low-quality trigger recursion guards based on static Booleans (people often call them something like runOnce
). Insert the Account, the trigger runs once. Do something else with the Account.... the trigger doesn't run again, because you're still in the same transaction and the static didn't get reset.
Side effects in your test data factory, in automation fired on Account insert, or interactions between those entities and your code under test can absolutely cause this kind of behavior change.
@testSetup
executes in a mostly-isolated transaction, insulating you from many of the potential side effects and code interactions between your setup process and your actual code under test. Removing that barrier opens a wide range of potential sources of interference, such as static variables that are not reset after test initialization, limits that have already been partially consumed, enqueued asynchronous actions, possible Mixed DML traps, and so on.
I would find this behavior somewhat surprising but not unheard-of while working with legacy or poorly-architected code, as it sounds like you are here.
One specific example where you can get this kind of weirdness is low-quality trigger recursion guards based on static Booleans (people often call them something like runOnce
). Insert the Account, the trigger runs once. Do something else with the Account.... the trigger doesn't run again, because you're still in the same transaction and the static didn't get reset.
answered Feb 16 at 17:59
David ReedDavid Reed
36.9k82255
36.9k82255
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
This is being caused by a "recursion blocker" (as mentioned by David Reed). The fix is to remove or correct the recursion blocker from your trigger logic. The reason why this happened is because static variables are reset between unit tests and test setup methods; as long as the trigger ran during test setup, it would have been reset for the unit tests. When the account is created within the unit test itself, the static variable is not reset, causing the behavior you see here.
To fix the problem, first try commenting out the recursion blocker logic and run some tests to make sure nothing breaks. If you get a "record is already in trigger" or "trigger depth exceeded" error, you'll need the recursion blocker, but you should modify it so it resets itself intelligently, or write "rising edge" trigger logic.
Here's my preferred form of recursion blocking:
static Boolean runOnce = false;
public static void beforeInsert(sObject records)
if(runOnce)
return;
runOnce = true;
doBeforeInsertLogicWith(records);
runOnce = false;
The secret sauce is the last line; by resetting the variable when the trigger contexts concludes, you'll fix the unit test problem and also allow the trigger to run correctly with batches of records larger than 200.
For rising edge triggers, you check to make sure the record will meet the condition, instead of checking if it already meets the condition.
Here's an example of this:
public static Boolean checkTransition(sobject oldRecord, sobject newRecord)
return oldRecord.get(someField) != newRecord.get(someField);
public static void handleRecords(sobject oldRecords, sobject newRecords)
sobject updates = new sobject[0];
for(Integer i = 0, s = newRecords.size(); i < s; i++)
if(checkTransition(oldRecords[i], newRecords[i]))
updates.add(newRecords[i]);
if(!updates.isEmpty())
doUpdatesOn(updates);
Obviously, these are meant more as pseudo-code, but hopefully you should be able to get to a fix using these ideas. Make sure you have a trigger unit test, and attempt to perform logic on at least 201 records in a single list, just to make sure that it is working appropriately either way.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
This is being caused by a "recursion blocker" (as mentioned by David Reed). The fix is to remove or correct the recursion blocker from your trigger logic. The reason why this happened is because static variables are reset between unit tests and test setup methods; as long as the trigger ran during test setup, it would have been reset for the unit tests. When the account is created within the unit test itself, the static variable is not reset, causing the behavior you see here.
To fix the problem, first try commenting out the recursion blocker logic and run some tests to make sure nothing breaks. If you get a "record is already in trigger" or "trigger depth exceeded" error, you'll need the recursion blocker, but you should modify it so it resets itself intelligently, or write "rising edge" trigger logic.
Here's my preferred form of recursion blocking:
static Boolean runOnce = false;
public static void beforeInsert(sObject records)
if(runOnce)
return;
runOnce = true;
doBeforeInsertLogicWith(records);
runOnce = false;
The secret sauce is the last line; by resetting the variable when the trigger contexts concludes, you'll fix the unit test problem and also allow the trigger to run correctly with batches of records larger than 200.
For rising edge triggers, you check to make sure the record will meet the condition, instead of checking if it already meets the condition.
Here's an example of this:
public static Boolean checkTransition(sobject oldRecord, sobject newRecord)
return oldRecord.get(someField) != newRecord.get(someField);
public static void handleRecords(sobject oldRecords, sobject newRecords)
sobject updates = new sobject[0];
for(Integer i = 0, s = newRecords.size(); i < s; i++)
if(checkTransition(oldRecords[i], newRecords[i]))
updates.add(newRecords[i]);
if(!updates.isEmpty())
doUpdatesOn(updates);
Obviously, these are meant more as pseudo-code, but hopefully you should be able to get to a fix using these ideas. Make sure you have a trigger unit test, and attempt to perform logic on at least 201 records in a single list, just to make sure that it is working appropriately either way.
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
This is being caused by a "recursion blocker" (as mentioned by David Reed). The fix is to remove or correct the recursion blocker from your trigger logic. The reason why this happened is because static variables are reset between unit tests and test setup methods; as long as the trigger ran during test setup, it would have been reset for the unit tests. When the account is created within the unit test itself, the static variable is not reset, causing the behavior you see here.
To fix the problem, first try commenting out the recursion blocker logic and run some tests to make sure nothing breaks. If you get a "record is already in trigger" or "trigger depth exceeded" error, you'll need the recursion blocker, but you should modify it so it resets itself intelligently, or write "rising edge" trigger logic.
Here's my preferred form of recursion blocking:
static Boolean runOnce = false;
public static void beforeInsert(sObject records)
if(runOnce)
return;
runOnce = true;
doBeforeInsertLogicWith(records);
runOnce = false;
The secret sauce is the last line; by resetting the variable when the trigger contexts concludes, you'll fix the unit test problem and also allow the trigger to run correctly with batches of records larger than 200.
For rising edge triggers, you check to make sure the record will meet the condition, instead of checking if it already meets the condition.
Here's an example of this:
public static Boolean checkTransition(sobject oldRecord, sobject newRecord)
return oldRecord.get(someField) != newRecord.get(someField);
public static void handleRecords(sobject oldRecords, sobject newRecords)
sobject updates = new sobject[0];
for(Integer i = 0, s = newRecords.size(); i < s; i++)
if(checkTransition(oldRecords[i], newRecords[i]))
updates.add(newRecords[i]);
if(!updates.isEmpty())
doUpdatesOn(updates);
Obviously, these are meant more as pseudo-code, but hopefully you should be able to get to a fix using these ideas. Make sure you have a trigger unit test, and attempt to perform logic on at least 201 records in a single list, just to make sure that it is working appropriately either way.
This is being caused by a "recursion blocker" (as mentioned by David Reed). The fix is to remove or correct the recursion blocker from your trigger logic. The reason why this happened is because static variables are reset between unit tests and test setup methods; as long as the trigger ran during test setup, it would have been reset for the unit tests. When the account is created within the unit test itself, the static variable is not reset, causing the behavior you see here.
To fix the problem, first try commenting out the recursion blocker logic and run some tests to make sure nothing breaks. If you get a "record is already in trigger" or "trigger depth exceeded" error, you'll need the recursion blocker, but you should modify it so it resets itself intelligently, or write "rising edge" trigger logic.
Here's my preferred form of recursion blocking:
static Boolean runOnce = false;
public static void beforeInsert(sObject records)
if(runOnce)
return;
runOnce = true;
doBeforeInsertLogicWith(records);
runOnce = false;
The secret sauce is the last line; by resetting the variable when the trigger contexts concludes, you'll fix the unit test problem and also allow the trigger to run correctly with batches of records larger than 200.
For rising edge triggers, you check to make sure the record will meet the condition, instead of checking if it already meets the condition.
Here's an example of this:
public static Boolean checkTransition(sobject oldRecord, sobject newRecord)
return oldRecord.get(someField) != newRecord.get(someField);
public static void handleRecords(sobject oldRecords, sobject newRecords)
sobject updates = new sobject[0];
for(Integer i = 0, s = newRecords.size(); i < s; i++)
if(checkTransition(oldRecords[i], newRecords[i]))
updates.add(newRecords[i]);
if(!updates.isEmpty())
doUpdatesOn(updates);
Obviously, these are meant more as pseudo-code, but hopefully you should be able to get to a fix using these ideas. Make sure you have a trigger unit test, and attempt to perform logic on at least 201 records in a single list, just to make sure that it is working appropriately either way.
answered Feb 16 at 20:00
sfdcfoxsfdcfox
258k12203447
258k12203447
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
Cheers for the feedback. We'll look into this!
– Brian Kessler
Feb 17 at 7:52
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f250582%2fhow-is-it-possible-for-testsetup-to-effect-test-result%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This code would not compile. Your first example references
doInsert
out of scope.– Adrian Larson♦
Feb 16 at 17:51
Sorry, that's a transcription error... this is a recreation, not the actual code. I'll fix that.
– Brian Kessler
Feb 16 at 17:54