1

Here's a fun one...I have a static @HTTP method creating metadata as a webservice. You can test metadata deployment containers, though not the actual deployment, as shown here, but apparently only if the method containing the deployment method is an instance method. Since mine is an @HTTP method, it must be static. It also must be void, so I can't use the result of it in my test.

    @HttpPost
    global static void createDO(String fullName, String label, Map<String, String> FieldsWithValuesMap){  

        Metadata.CustomMetadata DegOff = new Metadata.CustomMetadata();
        DegOff.fullName = fullName;
        DegOff.label = label;

        for(String Field : FieldsWithValuesMap.keySet()){ 
            Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();
            customField.field = Field;
            customField.value = FieldsWithValuesMap.get(Field);
            DegOff.values.add(customField);
        }

        Metadata.DeployContainer DOContainer = new Metadata.DeployContainer();
        DOContainer.addMetadata(DegOff);

        CreateDOService callback = new CreateDOService();

        If(!Test.isRunningTest()){
        Id jobId = Metadata.Operations.enqueueDeployment(DOContainer, callback);
        }
    }

The problem is, I can't create an instance of the static method in a test class, and if I call the method directly, there doesn't seem to be any way to query the results.

    @IsTest       
    public static void testCreateDO(){

        Map<String, String> DoFieldValues = new Map<String, String>{'Field 1' => 'Value 1', 'Field 2' => 'Value 2'};

        CreateDOService.CreateDO('fullName', 'label', DOFieldValues);

Once I've done the above, how could I verify Metadata.CustomMetadata DegOff or Metadata.DeployContainer DOContainer? Since this is fairly new salesforce functionality, I could imagine that there is no recourse on this yet.

I found this similar case, but it does not appear that the person was actually testing their deployment code.

Thanks!

4
  • 2
    Surely just factor out the method content into a separate non-static method that returns a value you need then write the @HTTP static method to instantiate the class, call the method and do whatever it needs with the returned data then test the non-static method to get most of your required coverage...? Or am I missing something?
    – Phil W
    Commented Sep 26, 2019 at 19:38
  • 1
    Another option would be to declare the variables as static variable defined at the class level (ie DegOff and DocContainer) or copy their contents in the function to class member static variables that are set as @TestVisible (so other classes aren't modifying or viewing it). Then you can just access the class variable from the test method. That should work in theory.
    – Roti
    Commented Sep 26, 2019 at 19:53
  • 1
    Both comments could be fine answers, Roti & Phil!
    – David Reed
    Commented Sep 26, 2019 at 21:14
  • N.B. I use andyinthecloud Custom Metadata Services package to deploy MDT. It has its own mocking support so you can assert you called it with proper args. As a package, it is fully tested.
    – cropredy
    Commented Sep 26, 2019 at 21:17

1 Answer 1

0

Thanks Phil and Roti, of course it was simpler than I thought. Solution below for those interested.

global class CreateDOService implements Metadata.DeployCallback{

    public static Metadata.DeployContainer DOContainer = new Metadata.DeployContainer(); 
    public static Id JobId;

    @HttpPost
    global static void createDO(String fullName, String label, Map<String, String> FieldsWithValuesMap){  

        Metadata.CustomMetadata DegOff = new Metadata.CustomMetadata();
        DegOff.fullName = fullName;
        DegOff.label = label;     

        for(String Field : FieldsWithValuesMap.keySet()){ 
            Metadata.CustomMetadataValue customField = new Metadata.CustomMetadataValue();
            customField.field = Field;
            customField.value = FieldsWithValuesMap.get(Field);
            DegOff.values.add(customField);
        }

        DOContainer.addMetadata(DegOff);

        CreateDOService callback = new CreateDOService();

        If(!Test.isRunningTest()){
        JobId = Metadata.Operations.enqueueDeployment(DOContainer, callback);
        }

And then the test class…

@IsTest       
    public static void testCreateDO(){

        //test container
        Map<String, String> DoFieldValues = new Map<String, String>{'Field 1' => 'Value 1'};

        CreateDOService.CreateDO('jsf-xyz', 'jsf-xyz', DOFieldValues);       

        List<Metadata.Metadata> DOcontents = CreateDOService.DOContainer.getMetadata();
            System.assertEquals(1, DOcontents.size());
        Metadata.CustomMetadata cmv = (Metadata.CustomMetadata) DOcontents.get(0);          
            System.assertEquals(cmv.fullname, 'jsf-xyz');           
        Metadata.CustomMetadataValue customFields = cmv.values.get(0);          
            System.assertEquals(customFields.field, 'Field 1');

You must log in to answer this question.

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