3

As the Vlocity documentation says, for Integration Procedure Unit Testing from Apex, we must use Salesforce seeAllData property.

In my case, the ideal would be to insert Order data for the test unit. Because this Integration Procedure only works for certain records, otherwise an exception will be thrown.But I saw that SetupTest is prohibited for SeeAllData=true.

I'm afraid that the other orgs don't have the proper type of Order and the exception will be thrown during the deploy.

So is it wrong to create a @IsTest makeData() to insert test data? What could I do in this case?

@isTest(seeAllData = true)
global class testUnitIP {

    @isTest
    public static List <Order> makeData() {

        Account acc = new Account();
        acc.Name = 'Account Business';
        insert acc;

        Order ord = OrderTestMethods.createOrder(acc.Id, 'International RecordType', 'In progress');
        insert ord;

        return [SELECT id FROM ORDER WHERE Id =: ord.id];
    }

    public static Set <String> setOrderId() {
        return (new Map <String, Order> (makeData())).keySet();
    }
    
    @isTest
    public static void CallIPTest() {
        Boolean hasError = false;
        try {
            VerifyOrder.callIP(setOrderId());
        } catch (Exception e) {
            hasError = true;
        }
        System.assert(hasError, 'Exception was not thrown');
    }
}
5
  • I work for an ISV. We have never found it necessary to have tests see all data - I believe this is simply something you should avoid, ensuring you either mock the data loading or ensuring you always insert test data as part of test setup.
    – Phil W
    Commented Apr 12, 2022 at 19:59
  • 1
    @PhilW there are some Chatter-related methods that require SeeAllData to work, but those are the rare exceptions.
    – sfdcfox
    Commented Apr 12, 2022 at 20:13
  • In this sort of scenario we avoid calling the Salesforce API where possible, mocking calls and simply checking if the required parameters are received. Of course, not all APIs can be mocked, so we sometimes have to split that code into a separate virtual method that we can override in the unit tests. It means, inevitably, there may be some small number of lines of code not actually unit tested, but 100% coverage is rarely sensible to aim for anyway.
    – Phil W
    Commented Apr 12, 2022 at 21:16
  • @Phil W In my case, I needed to use SeeAllData = true because I'm performing a test class to call the Integration Procedure (Vlocity)
    – Cline
    Commented Apr 13, 2022 at 0:40
  • That implies you are actually having a "unit test" that is literally invoking external systems, which means it isn't a unit test. It also will fail if the data changes or the external systems become unavailable. You should abstract out the actual call so your Apex unit test can mock it; this way it does not rely on actually doing the call, instead simply confirming that your code passes the right data and processes any response correctly. You can have a separate integration test (I recommend written using a separate testing framework) to verify that integration works.
    – Phil W
    Commented Apr 13, 2022 at 7:15

2 Answers 2

2

If you need a setup method like you describe, you do so without using @isTest (which would make it count as a unit test):

static void makeData() {
  Account a = createAnAccount();
  Contact c = createAContact(a);
  Order o = createAnOrder(a, c);
}

Where the various methods would do some kind of DML. In fact, this is how we used to do it before @testSetup was introduced, and it's still necessary in some rare cases.

Note that all side effects (inserts, updates, deletes, undeletes, whatever) are all rolled back as part of the test, so your production data will never be affected by anything that happens in the unit test. SeeAllData merely grants the unit test the ability to see production data it otherwise would not.

1

As per best practices it is advised to use SeeAllData=false

However, you can annotate the test method as @isTest(SeeAllData=true) instead of applying @isTest(SeeAllData=true) at the class level, like below:

    private class TestClass{
    
       @isTest(SeeAllData=true)
       static void testWithAllDataAccess() {
           // Can query all data in the organization.      
       }
    
       // Test method that has access to only the data it creates
       // and organization setup and metadata objects.
       @isTest static void testWithOwnDataAccess() {
          // Create your own data in this method, only data created 
          within this method will be available.
       }
    
    }

I hope, this will help you to write the test method using @isTest(SeeAllData=true) vs @isTest(SeeAllData=false)

0

You must log in to answer this question.

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