32

I was at dreamforce this year and I saw a session on testing and have looked online everywhere to try to find this trick the guy did. He was creating sObjects to complete dependencies of other sObjects but he did not insert these into the database. All of the objects were only in memory and he created fake IDs so that he could still link objects together and run his code that used IDs to operate on.

This would be huge for me to not have to insert into the database and run all my trigger code that has already been tested. Right now I have a test factory implemented that creates my objects and their dependencies and passes them to subsequent test methods but this is a really coupled design. Being able to do this small trick would allow me to create objects that I need completely in memory, increasing run time and making it much easier to test logic that relies on a large number of related objects.

I have tried a couple things like creating a UserRole Id by prefacing the Id with 00E and then 12 more random letters/numbers and also 15 more random letters and numbers. Maybe there is more depth to the Id field that I am missing. Any help with this would be greatly appreciated.

5
  • Do you know who ran the session? Many times they will attach the slides and code to the chatter feed for the session as well, so you might want to check that. Nov 24, 2013 at 13:04
  • 1
    Can you post some sample code that expresses the problem? Nov 25, 2013 at 15:04
  • 2
    That was my session, and as SF_Ninja suggests, I posted the slides on the session chatter thread, but you can now also get the slides from foobarforce.com/2013/11/25/df13return Nov 25, 2013 at 15:41
  • Yeah I found the chatter feed shortly after posting this. I forgot to update it, my apologies. Thank you for the excellent information!
    – Chris
    Nov 26, 2013 at 19:21
  • Excellent, glad you found it! Nov 27, 2013 at 10:51

2 Answers 2

49

Here's the fake ID test utility method as used in my DF13 "Tests and Testability" session:

public class TestUtility
{
   static Integer s_num = 1;

   public static String getFakeId(Schema.SObjectType sot)
   {
      String result = String.valueOf(s_num++);
      return sot.getDescribe().getKeyPrefix() + 
         '0'.repeat(12-result.length()) + result;
   }
}

Originally posted here: https://foobarforce.wordpress.com/2013/08/15/apex-method-of-the-day-string-repeat/

And here is a use of it:

Account a = new Account(Id=TestUtility.getFakeId(Account.SObjectType));
Opportunity o = new Opportunity(AccountId=a.Id);
10
  • 3
    Just a note for future rookies, if you make a fake ID you may be prevented from 'inserting' it into the db. If you need something inserted, just insert it without an Id and it will be added. Oct 1, 2014 at 18:01
  • 3
    Stephen, ..... this might sound strange, .... but I love you. For years now, I am trying to explain to people that in Unit Tests, data should never be inserted. This method of yours, is the last nail in the UT neewbie's coffin
    – user853710
    Oct 24, 2018 at 13:11
  • I recommend using the String.leftPad method rather than doing it with .repeat(). numStr.leftPad(12, '0') Jul 11, 2019 at 13:12
  • +1000 avoiding DML and SOQL in unit tests helps with performance, avoids breakages due to trigger and workflow changes, and forces you to structure your code such that testing business logic is isolated and more complete. Great solution!
    – Steve Cox
    Jan 9, 2020 at 1:31
  • 1
    Oops... nevermind... it helps if you use the correct SObject type!
    – Tim Lewis
    Oct 29, 2020 at 20:26
3

I think using the fflib_IdGenerator class would be a great help to you. Its on github open to all and its unit test is also available. You just need to use it and only pass the object name in the parameter. Id accTestId = fflib_IdGenerator.generate(Account.sObjectType);

You must log in to answer this question.

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