6

This is a canonical question and answer developed by the community to help address common questions. If you've been directed here, or your question has been closed as a duplicate, please look through the resources here and use them to shape more specific questions. To browse all canonical questions and answers, including more unit test resources, navigate to the canonical-qa tag.

This canonical question is intended to address several classes of common questions by providing a quick summary and links to comprehensive resources

  • When is it justified to use the annotation @IsTest SeeAllData=true?
  • Using SeeAllData=true sure makes my testing life easier, why is it recommended on this forum and elsewhere not to use it?
  • What does Test Isolation mean?
1

2 Answers 2

5

Overview

Salesforce enforces a nice discipline on developers - in order to deploy, Apex classes and triggers must demonstrate at least 75% code coverage across the code base. Code coverage is achieved by writing Unit Tests. Unit tests, properly designed, verify your logic and code paths.

For a unit test to work consistently as the code is deployed across orgs (from your sandbox/scratch org to CI orgs, to QA orgs, and finally to PROD), the test environment must be invariant to the test method. Salesforce recommends isolating Test Data from Organization Data in Unit Tests.

When you introduce SeeAllData=true into your testmethods, you are, in effect, altering the test environment as your code moves from org-to-org during your devops/deployment pipeline.

Example: A SOQL query that depends on a certain setup of Pricebooks and PricebookEntries might suddenly stop working as expected when those records are CRUD by the org users.

This might not seem like a big deal to you, the Apex hero at your org, but that environment can change over time, long after you are gone or long after you have forgotten your reliance on the setup nuances of org data that makes your tests run successfully.

What is Org Data?

  • Setup Data such as Users, Profiles, Groups, Folders, Roles, Sharing Rules, Custom Permissions, Custom Metadata, Custom Settings, etc.
  • Non-setup Data such as records for: Accounts, Opportunities, Product2s, and custom objects

Mocking Org Data

Almost all Salesforce SObjects can be mocked in a testmethod so you don't need to use SeeAllData=true. There are a variety of techniques, some easily enabled if you've adopted a design pattern.

  • Mocking by inserting SObjects using DML including Test.loadData, Test factories, TestSetup-annotated methods, and direct DML within the testmethod.
  • Mocking SObjects using new XXX(fldA='foo', fldB='bar', ...) and passing these SObjects to methods under test or by using dependency injection to have methods return these SObjects for use by other methods. A good example of this is the Selector pattern on Trailhead.
  • Mocking SObjects that don't support construction. Instead, use Json.deserialize. AsyncApexJob is a good example of this.
  • Mocking in-memory parent and child SObjects (see Third Party Testing Frameworks below)

If it seems like a lot of effort to mock up Accounts-Contacts-Opportunities-Quotes-Orders-etc (or some complex graph of custom objects), avoid falling into the SeeAllData=true trap and instead decompose your testing into pieces, verifying that each layer handles its inputs, marshals the correct arguments to supporting services and generates expected outputs. Good software architecture aids immeasurably here. One resource to consider is the Apex Enterprise Patterns Trailmix.

What about the Org Data that can't be mocked?

Some Org Data is always available to the testmethod without recourse to SeeAllData=true. For example, Folders, Profiles, StaticResources, Users. You should write your tests to be resilient so that if they require a specific Profile, that the test fails with an assert if that profile is not present.

I've mocked as much as possible, so when do I really need SeeAllData=true ?

Resources

Third-Party Testing Frameworks (Advanced Topics)

Books on Apex Testing Frameworks

3
  • I'm a bit leery of mentioning third party testing frameworks as it might open a bit of a can of worms.
    – Adrian Larson
    Commented Dec 28, 2018 at 1:38
  • How so, @AdrianLarson? The problem of defining relevance?
    – David Reed
    Commented Dec 28, 2018 at 1:48
  • @AdrianLarson - my two cents: Force-DI was featured at DF 18 in two sessions; ApexMocks is a natural extension to fflib which in turn is featured in TrailMix for Enterprise Patterns. I also think developers will adopt a framework with their eyes open. Skilled developers will say "this looks useful"; newbie developers will say "this looks too complicated" and avoid.
    – cropredy
    Commented Dec 28, 2018 at 2:03
-1

Great Post!!

I will also add one scenario in wich is mandatory to use this method(seeAlldata): Testing vlocity integration procedures.

Here the salesforce article about it: https://help.salesforce.com/s/articleView?id=sf.os_integration_procedure_unit_testing_from_apex_55739.htm&type=5

Here what its says:

Integration Procedure Unit Testing from Apex

You can set up a test class in Apex and use it to call and test an Integration Procedure. You must mock HTTP Action responses.

The following is an example unit test of an Integration Procedure:

@isTest(seeAllData=true)
global with sharing class TestVlocityIntergationProcedure
{
    static testMethod void testVip()
    {
        Map<String, Object> response = (Map<String, Object>)namespace.IntegrationProcedureService.runIntegrationService('Type_Subtype',
            new Map<String, Object>{
                'AccountName' => 'Vlocity'
            }, new Map<String, Object>());
        System.assertEquals('[email protected]', response.get('ContactEmail'));
    }
}

Note these features of the example:

  • You must use Salesforce's seeAllData property on the @isTest annotation. This ensures that the unit test sees the Vlocity SObject data in the org.
  • The method that runs the Integration Procedure is IntegrationProcedureService.runIntegrationService.
  • The namespace is vlocity_cmt, vlocity_ins, or vlocity_ps.
  • The Type_Subtype parameter specifies the Integration Procedure to test.

So basically, vlocity metadata act internally as records, so if your class depends on it, you have to use this anotation.

That being said, its not always necessary, as some say that there are alternatives.

For example: Is it wrong to put 'insert' in test class with SeeAllData = true?

In this post, someone asked about this topic, an it concivede some debate:

Question

Description

Comments

3
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – identigral
    Commented May 24, 2023 at 21:10
  • HI! i see your point, but why you downvoted me? .. I provided some helpful info. You can just tell me to correct the post, and I'll happily do it. Regards.
    – ian cacace
    Commented May 29, 2023 at 13:07
  • We did not downvote. Thanks for updating the answer!
    – identigral
    Commented May 29, 2023 at 17:03

You must log in to answer this question.

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