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!

  • 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 Sep 26 '19 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 Sep 26 '19 at 19:53
  • 1
    Both comments could be fine answers, Roti & Phil! – David Reed Sep 26 '19 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 Sep 26 '19 at 21:17
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');
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.