function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Bryan Leaman 6Bryan Leaman 6 

I need valid picklist value for record type in a test class

We have a picklist used by marketing to designate special pricing programs. This object in question also has several record types. Ideally, the same values would always be defined as available for all record types, but when they aren't my test class can't tell which ones are valid for the record I'm creating for the test. Also, I can't call out in a test to the metadata api to obtain valid values by record type. This picklist is a global picklist, so it must be restricted to the defined values.

How can I ensure my test class will always use valid values for the picklist?
Shri RajShri Raj
One way to ensure that your test class always uses valid values for the picklist is to create a static variable in your test class that stores the valid picklist values for the record type that you are testing. In the test class's @TestSetup method, you can query the object's record type to retrieve the valid picklist values for that record type and store them in the static variable. Then, in your test methods, you can use the static variable to ensure that you are always using a valid value for the picklist.
Another way to do this is by fetching the valid picklist values in test class constructor and use it in test methods.
You can also create a custom setting or custom metadata type with the picklist values and record type and use it in test class.
It's important to note that it is generally considered a best practice to use real data in test classes, so if it's possible to obtain valid picklist values for the record type you are testing, it's generally better to use those values than to hard-code them in the test class.
Shri RajShri Raj
@isTest
public class ExampleTest {

    // Static variable to store valid picklist values for record type
    private static Set<String> validPicklistValues;

    @TestSetup
    public static void setUp() {
        // Query record type to retrieve valid picklist values
        RecordType recordType = [SELECT Id, (SELECT ValidFor FROM PicklistValues) FROM RecordType WHERE SObjectType = 'Example__c' AND Name = 'RecordTypeName' LIMIT 1];
        validPicklistValues = new Set<String>();
        for (PicklistValue value : recordType.PicklistValues) {
            validPicklistValues.add(value.Value);
        }
    }

    @isTest
    public static void testMethod1() {
        // Create example object with valid picklist value
        Example__c example = new Example__c(PicklistField__c = 'ValidValue', RecordTypeId = 'RecordTypeId');
        insert example;

        // Check that the picklist value is valid
        System.assert(validPicklistValues.contains(example.PicklistField__c), 'Invalid picklist value used');
    }

    @isTest
    public static void testMethod2() {
        // Create example object with invalid picklist value
        Example__c example = new Example__c(PicklistField__c = 'InvalidValue', RecordTypeId = 'RecordTypeId');
        insert example;

        // Check that the picklist value is invalid
        System.assert(!validPicklistValues.contains(example.PicklistField__c), 'Invalid picklist value used');
    }
}

Here, in this example, the test class is testing a custom object named Example__c which has a picklist field named PicklistField__c and has a record type named RecordTypeName. The setUp method queries the RecordType object to retrieve the valid picklist values for the RecordTypeName record type and stores them in the validPicklistValues set. Then the test methods testMethod1 and testMethod2 insert the Example__c object with picklist value 'ValidValue' and 'InvalidValue' respectively and asserts whether the picklist value used is valid or not by checking in validPicklistValues set.
Bryan Leaman 6Bryan Leaman 6
Shri Raj, 
Did you try any of that code at all (like simply running it in anonymous apex)? The SOQL statement getting "ValidFor" doesn't work. There's no "PicklistValues" relationship to the RecordType object.
--Bryan
Shri RajShri Raj
@isTest
public class ExampleTest {
// Static variable to store valid picklist values for record type
private static Set<String> validPicklistValues;

@TestSetup
public static void setUp() {
    // Query record type to retrieve valid picklist values
    RecordType recordType = [SELECT Id, (SELECT Value FROM PicklistValues) FROM RecordType WHERE SObjectType = 'Example__c' AND Name = 'RecordTypeName' LIMIT 1];
    validPicklistValues = new Set<String>();
    for (PicklistValue value : recordType.PicklistValues) {
        validPicklistValues.add(value.Value);
    }
}

@isTest
public static void testPicklistValues() {
    // Create a record of the object using one of the valid picklist values
    Example__c example = new Example__c(Picklist_Field__c = validPicklistValues.iterator().next());
    insert example;

    // Verify that the value used in the record is still valid in the production environment
    Set<String> currentPicklistValues = new Set<String>();
    for (PicklistEntry entry : Example__c.Picklist_Field__c.getDescribe().getPicklistValues()) {
        currentPicklistValues.add(entry.getValue());
    }
    System.assert(currentPicklistValues.containsAll(validPicklistValues), 'One or more of the picklist values are no longer valid.');
}

}

 
Shri RajShri Raj
I believe the above should work. let me know