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 = 'Generated Testing' + GetRandomString();
    account.OwnerId = user.Id;
    account.RecordType = [SELECT Id FROM RecordType WHERE Name='Non-Third Party' AND SobjectType = 'Account' LIMIT 1];
    account.Account_Status__c = 'Active';
    account.Description = 'Used for testing.';
    account.NumberOfEmployees = 1;
    account.C_Level_Engagement__c = 'N';
    account.Transformation__c = 'N';
    account.Phone = '774-890-8876';
    account.County__c = 'Berkshire';
    account.State_Representative_District__c = 'Test 1';
    account.State_Senate_District__c = 'Test 1';
    account.Federal_Congressional_District__c = 'Test 1';
    account.Type = 'Other';
    account.NAICS_Code__c = '999999';
    account.No_Duns_Available__c = true;
    account.BillingCity = 'Test';
    account.NAICS_Description__c = 'TEST';
    account.BillingState = 'MA';
    account.BillingStreet = '21 Test Road';
    account.BillingPostalCode = '55190';

    return account;
}

I've also posted this issue onto the Salesforce developer forms.

  • 1
    Just tried this in my developer instance and I get the same exception. Seems very odd. – Mark Keats Apr 11 '16 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 – rael_kid Apr 11 '16 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 '16 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? – Daniel Ballinger Apr 26 '16 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 '16 at 18:23
13
+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.

  • 1
    FYI I couldn't reproduce on cs24. This test passes for me. – Adrian Larson Apr 26 '16 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. – Daniel Ballinger Apr 26 '16 at 20:58
  • Through Sublime/MavensMate. I checked through the UI and Dev Console, works there too. – Adrian Larson Apr 26 '16 at 21:00
  • Fails for me on NA2 – cropredy Apr 28 '16 at 3:05
  • 3
    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 '16 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

  • I tried this deserialize method, it doesnt work for account object, am i doing something wrong? – Pranay Jaiswal May 2 '16 at 4:52
  • 2
    @susanoochidori. Post a new question showing your code – cropredy May 2 '16 at 15:15
  • here is the link for new question. salesforce.stackexchange.com/questions/120281/… – Pranay Jaiswal May 3 '16 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 at 16:39
  • @Laxman - I'm not sure I understand your question – cropredy Jan 8 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.