17

I'm trying to get a number of records inserted into the database sometime in the past, to allow for a cleanup batch to have proper test coverage. I can use Test.setCreatedDate on the account I'm attaching a number of notes too, but I can't use it on the notes themselves.

@isTest 
public static void Test_SetCreatedDate() {
    Note n = new Note();
        
    n.Title = 'Naming Criteria';
    n.Body = 'Testing Note.';
    
    Account a = Generate.CreateAccount();
    
    insert a;
    
    n.ParentId = a.Id;
    
    insert n; 
        
    Test.setCreatedDate(a.Id, DateTime.now().addMonths(-6));
    Test.setCreatedDate(n.Id, DateTime.now().addMonths(-6));
    
    Test.startTest();
    
    a = [SELECT Id, CreatedDate FROM Account WHERE Id = :a.Id];
    n = [SELECT Id, CreatedDate FROM Note WHERE Id = :n.Id];
    
    System.assertEquals(DateTime.now().addMonths(-6), a.CreatedDate);
    System.assertEquals(DateTime.now().addMonths(-6), n.CreatedDate);
    
    Test.stopTest();
}

This code is failing with:

System.NoDataFoundException: The sObject with the ID 002m0000000m2rjAAA isn’t part of 
this transaction. Provide the ID of an sObject that this test method created.

As far as I can tell, this is a test method, with everything (including the Generate class), located in a test context.

Heres the Generate.CreateAccount function, requested in the comments. All it does is act as a scaffold to provide data that fulfills the requirements for record creation, without inserting a record.

private final static User user = [SELECT Id FROM User WHERE IsActive = true LIMIT 1];

@testVisible
private static Account CreateAccount() {
    Account account = new Account();
    
    account.Name = 'Test';
    account.OwnerId = user.Id;
    account.Description = 'Used for testing.';
    account.NumberOfEmployees = 1;

    // other fields 
    
    return account;
}
13
  • 1
    Just tried this in my developer instance and I get the same exception. Seems very odd.
    – Mark Keats
    Apr 11, 2016 at 15:09
  • 1
    Since this is a really new feature, it seems like a bug to me. Especially since it does work on the Account record, but it doesn't work for the Note record Apr 11, 2016 at 18:35
  • 1
    to work around this, use json.deserialize into the Note object; you can inject createdDate that way; there's an alternate strategy as well - code your production code to reference a static property today that testmethods can set to any value; then you insert sobjects with createdDate=today's date but the code can pretend to run in the past, present, or future
    – cropredy
    Apr 13, 2016 at 1:49
  • 1
    @battery.cord This will likely need a support case to raise the problem with Notes in setCreatedDate. Can you raise a case, or do you want me to raise one and feed the results back here? Apr 26, 2016 at 9:13
  • 1
    I am not able to reproduce this issue in my org, despite trying many variations and even a direct copy-paste from your post. It's not a universal issue.
    – Adrian Larson
    Apr 26, 2016 at 18:23

2 Answers 2

14
+50

I've raised support case 13752643 for the problem with Test.setCreatedDate not working with a Note that was created in the test method transaction. I'll relay the important updates from the case here.

See Known Issue Test.setCreatedDate() does not work for Note object

Update: 17th October - The known issue is now marked as "Fixed - Winter '17"


Repo code against v36.0 on na5.

@IsTest
public class Test_SettingCreatedDateOnNote {

    @isTest
    public static void CleanUp_Test() {
        Account testAccount = new Account();

        testAccount.Name = 'Test Account';

        insert testAccount;

        System.assertNotEquals(null, testAccount.Id);

        Note testNote = new Note();

        testNote.Title = 'Test Account Note';
        testNote.Body = 'Test Account Note Body.';
        testNote.ParentId = testAccount.Id;

        insert testNote;

        System.assertNotEquals(null, testNote.Id);

        Test.setCreatedDate(testAccount.Id, DateTime.now().addMonths(-6));
        Test.setCreatedDate(testNote.Id, DateTime.now().addMonths(-6));

        Test.startTest();

        System.assert([SELECT COUNT() FROM Note] > 0);

        Test.stopTest();
    }

}

The line Test.setCreatedDate(testNote.Id, DateTime.now().addMonths(-6)); throws the following exception:

System.NoDataFoundException: The sObject with the ID 0027000000VBxllAAD isn’t part of this transaction. Provide the ID of an sObject that this test method created.

6
  • 1
    FYI I couldn't reproduce on cs24. This test passes for me.
    – Adrian Larson
    Apr 26, 2016 at 20:45
  • @AdrianLarson Interesting. From the success page I put na5 and cs24 both on Spring '16 Patch 18.3 currently. I'll find a sandbox to try it on as well. How are you running the test case? I've used the developer console Run Test both sync and async. Both fail. Apr 26, 2016 at 20:58
  • Through Sublime/MavensMate. I checked through the UI and Dev Console, works there too.
    – Adrian Larson
    Apr 26, 2016 at 21:00
  • Fails for me on NA2
    – cropredy
    Apr 28, 2016 at 3:05
  • 4
    I predict your next update reads: We are logging an investigation on the issue for the R&D to determine if this is a bug. The team is looking into the issue. I will keep you updated on the status with my next update between 4 and 5 PM Pacific time tomorrow.
    – cropredy
    May 3, 2016 at 0:44
10

For argument's sake, let's assume SFDC will fix the issue with

Test.setCreatedDate(n.id,someDateTime)

but, until then, two workarounds

JSON deserialize

Note n = (Note) Json.deserialize('{"createdDate" : "2016-01-01T00:00:00Z",' +
                                   '"title" : "foo",' +
                                   '"body" : "fooBody",' +
                                   '"parentId" : "' + a.id + '"' +
                                  '}',
                                  Note.class);
insert n; 

Static property in some Util class

public static Date todayDate {
   get {return todayDate == null ? Date.today() : todayDate;}
   set;
}

public static DateTime nowTime {
   get {return nowTime == null ? DateTime.now() : nowTime;}
   set;
}

Change all your code references from ...Date.today()... to ...Util.todayDate...

for example,

if (myNote.createdDate < Util.nowTime) ...

or

[select id , ... from Opportunity where closeDate < : Util.todayDate]

now, your testmethods can set today's date (or now time) to any value in the past, present, or future before or after the objects are created or referenced

6
  • I tried this deserialize method, it doesnt work for account object, am i doing something wrong? May 2, 2016 at 4:52
  • 2
    @susanoochidori. Post a new question showing your code
    – cropredy
    May 2, 2016 at 15:15
  • here is the link for new question. salesforce.stackexchange.com/questions/120281/… May 3, 2016 at 7:22
  • Thank you!! very much cropredy, actually I stuck here to deploy my code to production. Now I am able to deploy my code to prod with the util class provided by you.
    – Laxman
    Jan 8, 2019 at 16:39
  • @Laxman - I'm not sure I understand your question
    – cropredy
    Jan 8, 2019 at 18:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .