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
Andy Kallio 7Andy Kallio 7 

Test method that creates metadata

Hello friends. I have a method that creates records in custom metadata. It works as expected but now I am having a hard time figuring out how to get test coverage for it. 

Initially got an error on the line that enques the deployment via Metadata.Operations.enqueueDeployment which said that metadata cannot be deployed in a test context.

Then I found the suggestion of just skipping that line with a ternary operator, which is the version I have posted here. And that gives me 'Fake Job Id' is not a proper id. Strange that this seems to have worked for other people on that stackexchange post. 

 

At this point I need to seek some advice from those of you that are more experienced. Thanks!!

 

@future
    public static void createCustomMetaData(string acctName, string acctId) {

    string fullname = 'Product_Selection_Search_Parameter.'+acctName.replace(' ','_');    
    // Set up custom metadata to be created in the subscriber org. thanks to https://www.sfdcpanther.com/create-update-custom-metadata-using-apex/
    Metadata.CustomMetadata customMetadata =  new Metadata.CustomMetadata();
    customMetadata.fullName = fullname;
    customMetadata.label = acctName;

    Metadata.CustomMetadataValue typeField = new Metadata.CustomMetadataValue();
    typeField.field = 'Type__c';
    typeField.value = 'Top-Up';
	Metadata.CustomMetadataValue acctField = new Metadata.CustomMetadataValue();
    acctField.field = 'Value__c';
    acctField.value = acctId;

    customMetadata.values.add(typeField);
	customMetadata.values.add(acctField);

    Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();
    mdContainer.addMetadata(customMetadata);

    // Setup deploy callback, MyDeployCallback implements
    // the Metadata.DeployCallback interface 
    CustomMetadataCallback callback = new CustomMetadataCallback();

    // Enqueue custom metadata deployment
    // jobId is the deployment ID
    Id jobId = Test.isRunningTest() ? 'Fake Job Id' : Metadata.Operations.enqueueDeployment(mdContainer, callback);
    }

Here is the test class
@isTest
public with sharing class di_PartnerCreation_Test {
    
    @TestSetup
    static void makeData(){
        TestData_Research_Director director = new TestData_Research_Director();
        director.Construct_Account(new TestData_Research(), true);
        director.Construct_NonStandardPBE(new TestData_Research(), true);
    }

    public static testMethod void testDIPartnerCreationMethods_Act() {
        Account act = [select Id, Name from Account limit 1];
        PriceBook2 pb = [select Id from PriceBook2 where IsStandard = false];

        map<string, string> pbTest = di_PartnerCreation_lcController.getPriceBookOptions(act, 'AUD');
        boolean exProds = di_PartnerCreation_lcController.hasExistingProducts(act.Id);
        di_PartnerCreation_lcController.createProducts(act, 'AUD');
        di_PartnerCreation_lcController.createPriceBookEntries(act, 'AUD', pb.Id);
    }

    public static testMethod void testDIPartnerCreationMethods_NoAct() {

        map<string, string> currencyMap = di_PartnerCreation_lcController.getCurrencies();

    }
}

 
Best Answer chosen by Andy Kallio 7
MKRMKR
Hi,

I would propose that you formulate the test check as follows:
 
Id jobId;
if (!Test.isRunningTest()) {
    jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);
}

So no need for any fake id. Populate the jobId only when you are not running in test context. When running tests, keep the jobId as null.

Regards,
Mkr

All Answers

MKRMKR
Hi,

I would propose that you formulate the test check as follows:
 
Id jobId;
if (!Test.isRunningTest()) {
    jobId = Metadata.Operations.enqueueDeployment(mdContainer, callback);
}

So no need for any fake id. Populate the jobId only when you are not running in test context. When running tests, keep the jobId as null.

Regards,
Mkr
This was selected as the best answer
MKRMKR
Hi,

And one addition. If you want to assert something in the tests for createCustomMetaData method, I'd propose that you create a separate method that generates the Metadata.DeployContainer and validate its content. See the following trailhead unit for additional insights:

https://trailhead.salesforce.com/content/learn/modules/apex_metadata_api/apex_metadata_api_testing

Regards,
Mkr
Andy Kallio 7Andy Kallio 7
that was easy. thanks for that. 
numberforty1numberforty1
Hi Andy, was looking at this because I'm in a similar place. I noticed your createCustomMetaData method is not being called in your test, so how is it being tested? My issue is that I also have a static method creating metadata, but you can't create an instance of a static method in a test class, and if you call the method directly there doesn't seem to be any way to query the results. In my case the method is an @HttpPost request as well, which makes it interesting.