1

I am trying to get my code coverage up and I have a class where I am getting responses from an endpoint.

I need to get different responses for different tests. Ex: Test Method 1 I need to simulate mock response 1, test method 2 I need to simulate mock response 2.

I have created new simulated responses in a class called MockApiCalls, but I only want to execute certain Mocks for specific tests.

Setting the mock in the test (SFEndpointMock) doesn't seem to stick, no response is returned when the myClass calls out.

HOWEVER, in myClass, there is a conditional for Test.isRunningTest() where a response is returned when I use MockApiCalls.

When I comment out MockApiCalls in the class and keep the .setMock in the test method I get no response when the class is being tested, but when I comment out the .setMock and keep the MockApiCalls in the class, I get a response.

I am assuming it has something to do with the scope of Test.mock in the test method, it must not be carrying over when the .peformRequest method is being invoked, but I can't understand why. Whether or not this is the case, I'm not sure how I would get it to be available during the class test.

Test Methods:

@isTest static void testMethodOne() {
        Test.StartTest();
        Test.setMock(HttpCalloutMock.class, new SFEndpointMock());
        SFEndpointMock.indicatorVar ='success';
        Test.StopTest();
       myClass.performRequest('testData1');
    }

@isTest static void testMethodTwo() {
        Test.StartTest();
        Test.setMock(HttpCalloutMock.class, new SFEndpointMock());
        SFEndpointMock.indicatorVar ='success';
        Test.StopTest();
       myClass.performRequest('testData2');
    }

SFEndpointMock

@isTest
 global class SFEndpointMock implements HttpCalloutMock {
 public static String indicatorVar;
 global HttpResponse respond(HTTPRequest req){
        HttpResponse res = new HttpResponse();
        if(indicatorVar== 'success') {
            res.setStatus('OK');
            res.setStatusCode(200);
            String json = ***JSON BODY HERE***
            res.setBody(json);

      }  

else if (indicatorVar== 'success2') {
            res.setStatus('OK');
            res.setStatusCode(400);
            String json = ***DIFFERENT JSON BODY HERE***
            res.setBody(json);

      }  
    return res;

In myClass, the class I am trying to get code coverage up on:

  if(!Test.isRunningTest()) {

                res = http.send(request);
            }

            else {

                res= MockApiCalls.WebserviceExpectedResponse1();
            }    

MockApiCalls:

public class MockApiCalls {
    public static HttpResponse WebserviceExpectedResponse1() {
         HttpResponse res = new HttpResponse();
         String json = ***JSON BODY HERE***
         res.setBody(json);
         res.setStatusCode(200);
         return res;

    }

public static HttpResponse WebserviceExpectedResponse2() {
             HttpResponse res = new HttpResponse();
            String json = ***DIFFERENT JSON BODY HERE***
            res.setBody(json);
             res.setStatusCode(400);
             return res;

        }
  }

3 Answers 3

1

Sorry i now i understnding. You don't need this if :

    if(!Test.isRunningTest()) {
        res = http.send(request);
    }
    else {
        res= MockApiCalls.WebserviceExpectedResponse1();
    }    

Replace to this :

res = http.send(request); 

because the test class return you response. You set response in class SFEndpointMock. You don't need make other mock class this is redundant.

i want to help you.

0
1

I vaguely recollect not being able to set values on the mock as if its state is serialised and then deserialised per HTTP callout.

So try changing to this pattern:

@isTest global class SFEndpointMock implements HttpCalloutMock {
    private String indicatorVar;
    global SFEndpointMock(String indicatorVar) {
        this.indicatorVar = indicatorVar;
    }
    global HttpResponse respond(HTTPRequest req){
        ...
    }
}

and:

Test.setMock(HttpCalloutMock.class, new SFEndpointMock('success'));
2
  • Thank you! I tried it your way after adding the http.send for the test conditional, then wondered if it was because I didn't have the send in before and It actually works both ways, I was just missing the http.send(request) for when the isRunningTest was true. facepalm
    – S.B.
    Commented May 25, 2018 at 17:51
  • @S.B. Good to know and glad you got it sorted. Best you un-accept this as an answer as it wasn't the problem.
    – Keith C
    Commented May 25, 2018 at 17:53
0

Put StopTest after you call your class. Because StopTest() executes immediately

myClass.performRequest('testData1'); Test.StopTest();

You must log in to answer this question.

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