Following scenario:

Let's say I have a Process Builder that populates a lookup field with a specific record using its Id. The Id is "hard-coded" into the action of the Process Builder (which means it's not a reference).

A few weeks later I write some random Apex Class and its respective Test Class. The Test Class is triggering the Process Builder but fails since (of course) the Id of this one record from the Process Builder cannot be found. It would work if I'd prefix the Test Class with SeeAllData=true. But I don't want to use this backdoor.

Are there better solutions than using SeeAllData=true to make the Test Class work in this case?


You should always try to avoid hardcoding record ids. It can be troublesome on sandboxes or, as you can see, in tests. You could consider moving the id from the process builder action into a custom setting which then can be referenced and created in sandboxes and test methods.

  • Storing Id in custom setting is still essentially hard coding.
    – Adrian Larson
    May 29 '20 at 14:05
  • Thx for your answer, Paweł. Moving away from hard-coding Ids is a good point. I also agree with Adrian. If we'd use a Custom Setting the Id would be dressed as a String variable. That's almost the same as adding the Id directly into the code. It wouldn't solve the issue since the record doesn't exist in the test context. My current solution: Since the records I need have a unique name in the db I query the names and reference the Id. It gives me the chance to create them in my Test Classes. For use cases where the name is not unique one could create an editable field that holds a unique value.
    – Daniel
    May 29 '20 at 16:54
  • Custom settings have to be created in tests so you would put the id of a test record in there. I don't see how it's hardcoding. May 30 '20 at 17:27
  • Let's say I create a Custom Setting record in the Test Class and assign an Id to some Custom Setting field in order to reference it later in a lookup. This will not work. This particular Id (and therefore the record) is not in the "database" of the Test Class scope - unless you prefix the Test Class with SeeAllData=True which I don't want. That's the dilemma. But anyways, I think I will change my approach on a general design level.
    – Daniel
    Jun 1 '20 at 17:18
  • Yes, it won't see the real record and it never should. What I meant was to create a record in the test class and assign it's id to the custom setting. If I understand correctly the alternative is to implement some additional logic to find the record instead of storing the id so you're creating the test data anyway. I don't know your org so I'm not going to try to tell you what you can and what you cannot do, I just think it's not a good direction to implement additional logic eating cpu and soql limits if it's just a case of finding an id which could be stored in a custom setting. Jun 2 '20 at 8:52

So, best practice is to never put hard-coded IDs into Apex, PBs, or Flows. In our org, any pull request that includes hard-coded IDs is immediately sent back to the developer for change.

What you want in this use case is for the Process Builder to delegate its work of finding and assigning the appropriate lookupId to either:

  • Invocable Apex
  • Lightning Flow

In either use case, you would save the criteria (or even the entire SOQL query) in some piece of known reference data (such as a Custom Setting, Custom Metadata, or even Custom Label). This has several benefits:

  • It decouples your implementation from an org (where Ids will differ)
  • It allows for apex testmethods to mock the reference data, thus allowing the PB/Flow to be deployed activated as you can get flow coverage satisfied.
  • It allows the application to alter its behavior as business rules change without having to do any coding (point-and-click or otherwise)

You can also dispense with the PB entirely with Summer 20 as after save Flows are offered, providing a declarative automation hook with much more expressive power to do logic

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.