How Can We Handle Custom Metadata in Unit Tests?

How Can We Handle Custom Metadata in Unit Tests?

On June 7, 2025, Posted by , In Apex,Salesforce Technical Questions, By ,, , With Comments Off on How Can We Handle Custom Metadata in Unit Tests?
How Can We Handle Custom Metadata in Unit Tests?

Question

I’ve been working extensively with Custom Metadata in Apex, but I haven’t been satisfied with most solutions I’ve found online, whether from Salesforce or other sources.

I have a few specific questions:

  1. Is it possible to create Custom Metadata records in a test class? I tried doing so but encountered an error stating that the fields of the metadata are not writable.
  2. If it’s not possible to create metadata records within test classes, does that mean we must rely on real values from existing Custom Metadata records when running tests?
  3. If the answer to the previous question is yes, does that mean we need to ensure the necessary Custom Metadata records exist in the target environment before deployment?

Answer

No, it is not possible to create Custom Metadata records in test code, and there are strong reasons why Salesforce enforces this limitation. Custom Metadata is part of the org’s configuration, not its data. Allowing test classes to modify metadata would blur the critical distinction between metadata and data, leading to unpredictable behaviors. If test code could change metadata, it could create serious headaches for administrators by introducing unexpected setup changes during test execution.

The prevailing advice is to create “test” metadata records in the org and use them for unit tests. However, this approach doesn’t always make sense. For example, if your Custom Metadata defines system-wide defaults, you may need to test how your code reacts to different configuration values. Creating additional “test” metadata records for such cases is often impractical.

A better approach is to design the code so that Custom Metadata is accessed through a wrapper class. This allows test classes to override the configuration programmatically without relying on actual metadata records. Here’s an example of how this can be structured:

@testVisible
private static OrderConfigurationSetting setting {
    get {
        if (setting == null) {
            Order_Configuration_Settings__mdt metadata = [
                SELECT
                    Batch_Run_Frequency__c,
                    Duplicate_Day_Range__c,
                    Qty_Minimum__c
                FROM Order_Configuration_Settings__mdt
                WHERE DeveloperName = :DEFAULT_SETTING_NAME
            ];
            setting = new OrderConfigurationSetting(
                metadata.Batch_Run_Frequency__c,
                metadata.Duplicate_Day_Range__c,
                metadata.Qty_Minimum__c
            );
        }
        return setting;
    }
    set;
}

@testVisible
private class OrderConfigurationSetting {
    public String batchRunFrequency;
    public Integer duplicateDayRange;
    public Integer qtyMinimum;

    public OrderConfigurationSetting(
        String batchRunFrequency,
        Decimal duplicateDayRange,
        Decimal qtyMinimum
    ) {
        this.batchRunFrequency = batchRunFrequency;
        this.duplicateDayRange = Integer.valueOf(duplicateDayRange);
        this.qtyMinimum = Integer.valueOf(qtyMinimum);
    }
}

This code snippet defines a structured approach to accessing Custom Metadata records in Apex while allowing flexibility for unit testing.

The first part of the code is a static property named setting, which is responsible for retrieving and caching an instance of OrderConfigurationSetting. The get method ensures that the metadata is only queried once per execution context by checking if setting is null. If it hasn’t been initialized, it queries the Order_Configuration_Settings__mdt Custom Metadata Type, selecting specific fields (Batch_Run_Frequency__c, Duplicate_Day_Range__c, and Qty_Minimum__c) for a predefined record identified by DEFAULT_SETTING_NAME. The retrieved metadata values are then passed to the constructor of the OrderConfigurationSetting class, creating an instance that holds the parsed values. This ensures that the metadata is processed into a structured format before being used elsewhere in the code.

The OrderConfigurationSetting class acts as a wrapper to store the metadata values in strongly-typed fields. It defines three attributes: batchRunFrequency as a String, and duplicateDayRange and qtyMinimum as Integer. Since Salesforce stores numeric metadata fields as Decimal, the constructor explicitly converts duplicateDayRange and qtyMinimum from Decimal to Integer using Integer.valueOf().

By using this approach, the actual metadata values are abstracted away from the rest of the codebase, making it easier to override them in test classes. The @testVisible annotation allows unit tests to modify the setting variable directly, enabling test cases to simulate different configurations without needing actual Custom Metadata records in the org. This design pattern improves testability, ensures data consistency, and prevents unnecessary metadata queries during execution.

This pattern allows for a clean separation between metadata and business logic. In unit tests, you can directly set the setting variable to mimic different configuration scenarios, eliminating the need to rely on real metadata records.

This approach ensures that tests remain self-contained and do not depend on the state of Custom Metadata records in the org, making them more reliable and easier to maintain.

Job-Oriented Salesforce Training with 100% Money Back Guarantee

Our Salesforce Course is designed to provide a comprehensive understanding of the Salesforce platform, equipping you with the essential skills to thrive in the CRM industry. The program covers key modules such as Salesforce Admin, Developer, and AI, combining theoretical learning with hands-on experience. Through real-world projects and practical exercises, you will gain the expertise needed to tackle complex business challenges using Salesforce solutions. Our expert trainers ensure you develop both technical proficiency and industry-relevant knowledge to excel in the Salesforce ecosystem.

Beyond technical skills, our Salesforce Training in Singapore offers personalized mentorship, certification guidance, and interview preparation to enhance your career opportunities. You will have access to in-depth study materials, real-world project exposure, and dedicated support throughout your learning journey. By the end of the program, you will be fully prepared for certification exams and possess the problem-solving skills that employers seek. Take the first step toward a successful Salesforce career with us—Sign up for a Free Demo today!

Comments are closed.