Can Custom Metadata Be Created in Test Classes?
Question:
I have three questions regarding using Custom Metadata in Salesforce test classes:
- Is there any way to create Custom Metadata records in test classes? I attempted to create them within a test class but encountered an error stating that the fields of the metadata are not writable.
- If Custom Metadata records cannot be created in test classes, does that mean we need to declare actual values in the Custom Metadata and use them in our test classes?
- If the second point is correct, does this imply that we must create the necessary Custom Metadata records in the environment where we are deploying our code before proceeding with the actual deployment?
CRS Info Solutions provides top-notch Salesforce training with real-time projects, certification guidance, interview coaching, and a practical, job-ready approach.
Answer:

Custom Metadata records cannot be created in test classes. This is an intentional design choice by Salesforce to maintain a clear distinction between metadata and data. Custom Metadata is primarily configuration information that is meant to be managed declaratively by administrators, not programmatically by developers within code. Allowing test classes to create or manipulate Custom Metadata would undermine this separation and could lead to unpredictable behavior in managed environments.
If you need to test behavior dependent on Custom Metadata, there are a few approaches you can take:
Approach 1: Use Real Custom Metadata Records
It involves leveraging actual Custom Metadata records in test classes by inserting them beforehand or using @testSetup
methods. This ensures that the test class interacts with realistic data, validating behavior in real-world scenarios. However, Salesforce restricts direct creation in test methods, requiring the use of data loaded through setup methods or data imported prior to testing.
Example :
@testSetup
static void setupMetadata() {
CustomMetadata__mdt metadataRecord = new CustomMetadata__mdt(
DeveloperName = 'TestMetadata',
MasterLabel = 'Test Label',
Field1__c = 'Value'
);
insert metadataRecord;
}
@isTest
private class TestCustomMetadata {
@isTest
static void testWithRealMetadata() {
CustomMetadata__mdt metadata = [SELECT Field1__c FROM CustomMetadata__mdt WHERE DeveloperName = 'TestMetadata' LIMIT 1];
System.assertEquals('Value', metadata.Field1__c);
}
}
Code explanation : The code demonstrates how to use real Custom Metadata records in test classes by setting them up with the @testSetup
method, which inserts a CustomMetadata__mdt
record. The test class TestCustomMetadata
retrieves this record and validates that the Field1__c
value is correctly stored. This approach ensures that tests interact with realistic metadata while complying with Salesforce’s restrictions on creating Custom Metadata directly in test methods.
Approach 2: Simulate Custom Metadata with a Wrapper Class
Simulating Custom Metadata with a wrapper class involves creating a custom Apex class that mimics the structure and behavior of Custom Metadata records. This allows developers to test logic that interacts with metadata without actually relying on real metadata records in Salesforce. By using mock data within the wrapper class, developers can ensure tests remain isolated and independent of actual metadata, while still validating business logic. Here’s an example:
Wrapper Class and Metadata Handler:
@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);
}
}
Code explanation : The code defines a lazy-loaded singleton property setting
of type OrderConfigurationSetting
, which retrieves values from a custom metadata type (Order_Configuration_Settings__mdt
) when first accessed and caches the result. The OrderConfigurationSetting
inner class stores configuration values and converts Decimal
fields to Integer
where necessary. The @testVisible
annotation allows unit tests to access these otherwise private members for testing purposes.
OrderConfigurationSetting
Class
@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);
}
}
Code explanation : The OrderConfigurationSetting
class is a private Apex class with the @TestVisible
annotation, making it accessible in test classes. It defines three public properties (batchRunFrequency
, duplicateDayRange
, and qtyMinimum
) and a constructor that initializes them, converting Decimal
inputs to Integer
where needed.
Approach 3: Use Test-Specific Metadata
Using test-specific metadata involves creating mock or test-specific metadata records that mimic real metadata behavior without affecting the actual configuration. This can be achieved by using custom classes, static variables, or mock data in test methods, allowing for isolated and repeatable tests. This approach ensures that tests can run independently of the environment’s metadata, maintaining test integrity while avoiding the need to modify real metadata records.
Summing Up
Salesforce restricts the creation of Custom Metadata in test classes to maintain the distinction between metadata and data, ensuring consistent and stable configuration across environments. To work around this, developers can abstract metadata access into service layers, using mock data or static variables for testing purposes. This approach supports isolated testing, encourages maintainable code design, and avoids compromising metadata integrity.
Empower Your Career with Salesforce Training in New York
Elevate your professional journey with CRS Info Solutions’ top-rated Salesforce training, crafted to provide the skills and expertise required to excel in the ever-evolving Salesforce ecosystem. Our industry-focused courses span Salesforce Admin, Developer, and AI modules, blending in-depth theoretical knowledge with hands-on experience through practical, real-world projects.
With a strong emphasis on practical application, Salesforce training in New York, USA we offer personalized mentorship, detailed study resources, and expert-led certification preparation to fully equip you for success in interviews and beyond. Gain the confidence and skills to thrive in your Salesforce career.
Join our free demo class today and take the first step toward a rewarding future! Enroll now for a free demo!!!
Related Posts :