0

Can anyone help me understand how to write a test method/or generate mock response when using MetadataService.cls

Here is the line which I am trying to cover

MetadataService.ApprovalProcess approvalProcess
        = (MetadataService.ApprovalProcess) service.readMetadata(Constants.METADATA_API_TYPE_APPROVAL_PROCESS,
                                                                    new String[] { approvalProcessName }).getRecords()[0];

I am trying to generate a mock response for this callout. I tried generating a very basic response using

Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());

My MockHttpResponseGenerator looks like below

public class MockHttpResponseGenerator implements HttpCalloutMock {
    public HTTPResponse respond(HTTPRequest req) {
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setStatusCode(200);
        return res;
    }
}

I am getting "Methods defined as TestMethod do not support Web service callouts" – I thought there would be some kind of global MockResponse implementation within MetadataService.cls which could be leveraged to generate mock response.

5
  • What have you tried so far? Where are you stuck? You cannot test private methods directly, so you either need to manipulate other methods which in turn call this method, or it is not being used and you should remove it from your class.
    – Adrian Larson
    Commented Jul 28, 2017 at 0:34
  • Hey Adrian, this is snippet where I get exception during testing but you are right; I am calling this method from another apex class which is a public method. I am basically trying to have a mock response generated for this callout so I can cover this line MetadataService.ApprovalProcess approvalProcess = (MetadataService.ApprovalProcess) service.readMetadata(Constants.METADATA_API_TYPE_APPROVAL_PROCESS, new String[] { approvalProcessName }).getRecords()[0];
    – Vinar
    Commented Jul 28, 2017 at 0:41
  • Please edit your post with any clarifications, especially what you have tried so far.
    – Adrian Larson
    Commented Jul 28, 2017 at 0:42
  • What does your test class look like? You need to call the method that eventually makes the fallout between test start and stop
    – Eric
    Commented Jul 28, 2017 at 3:07
  • Thanks guys, I was dumb to use HTTPMock instead of WebServiceMock. I was able to use the snippet posted below; modify it to my response type make it work.
    – Vinar
    Commented Jul 31, 2017 at 23:21

3 Answers 3

2

For MetadataService.cls you need to implement WebServiceMock instead of HttpCalloutMock.To create webservice mock follow the Link

Ex Webservicemock for connected app.

global with sharing class CallOutMock implements WebServiceMock{
global void doInvoke(
    Object stub,
    Object request,
    Map<String, Object> response,
    String endpoint,
    String soapAction,
    String requestName,
    String responseNS,
    String responseName,
    String responseType) {
        MetadataService.createMetadataResponse_element metadataResponse = new MetadataService.createMetadataResponse_element();
        MetadataService.SaveResult saveresult = new MetadataService.SaveResult();
        saveresult.errors = new List<MetadataService.Error>();
        saveresult.errors.add(eror);
        saveresult.fullName = 'TestApp';
        saveresult.success = true;
        metadataResponse.result = new List<MetadataService.SaveResult>();
        metadataResponse.result.add(saveresult);
        response.put('response_x', metadataResponse); 
    }}
1
  • Thank you very much @ajay-prakash-dubey. Thats all the direction I needed. I was successfully able to implement WebServiceMock and everything flowed smoothly.
    – Vinar
    Commented Jul 31, 2017 at 23:17
1

In my case, I was trying to get Assignment Rules from readMetadata and here's how I mocked it:

 private class WebServiceMockImpl implements WebServiceMock 
{
    public void doInvoke(
        Object stub, Object request, Map<String, Object> response,
        String endpoint, String soapAction, String requestName,
        String responseNS, String responseName, String responseType) 
    {
  if(request instanceof MetadataService.readMetadata_element){
    response.put('response_x', new MetadataService.readAssignmentRulesResponse_element());
  }
        return;
    }
}  
0

In case it isn't obvious, the exact test code needs to be tailored to the specific MetadataService call you are making. For example, if you are reading a Custom Label in your code like this:

MetadataService.ReadCustomLabelResult labelReadResult = (MetadataService.ReadCustomLabelResult) this.service.readMetadata('CustomLabel','myLabel');

Then your test code within the doInvoke method would look like this:

    if(responseType.equals('MetadataService.readCustomLabelResponse_element')){

        MetadataService.readCustomLabelResponse_element labelRslt = new MetadataService.readCustomLabelResponse_element();
        MetadataService.ReadCustomLabelResult readResult = new MetadataService.ReadCustomLabelResult();
        MetadataService.CustomLabel lbl = new MetadataService.CustomLabel();

        lbl.fullname = 'labelFullname';
        lbl.value = 'labelValue';

        readResult.records = new List<MetadataService.CustomLabel>();
        readResult.records.add(lbl);

        labelRslt.result = readResult;
        response.put('response_x', labelRslt);

    }

If you are updating Custom Labels in your code with a call like:

this.service.updateMetadata(listLabels);

Then you would need test code within doInvoke like this:

    if (responseType.equals('MetadataService.updateMetadataResponse_element'))
    {
        MetadataService.updateMetadataResponse_element metadataResponse = new MetadataService.updateMetadataResponse_element();
        MetadataService.SaveResult saveresult = new MetadataService.SaveResult();

        saveresult.errors = new List<MetadataService.Error>();
        saveresult.fullName = 'TestApp';
        saveresult.success = true;

        metadataResponse.result = new List<MetadataService.SaveResult>();
        metadataResponse.result.add(saveresult);

        response.put('response_x', metadataResponse);
    }

You must log in to answer this question.

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