3

Firstly, I know what this message is trying to tell me:

Methods defined as TestMethod do not support Web service callouts

And I believe I have set up all the HttpCalloutMock's correctly, because the other 40 unit tests which failed are now passing.

I have a class/method MockFactory.create() which creates StaticResourceCalloutMock for the 4 end points I call out to.

@isTest
public class MockFactory {

    public static HttpCalloutMock create() {

        StaticResourceCalloutMock contactMock = getStaticMock(200, 'ContactsMock');
        StaticResourceCalloutMock invoiceMock = getStaticMock(200, 'InvoicesMock');
        StaticResourceCalloutMock creditNoteMock = getStaticMock(200, 'CreditNotesMock');
        StaticResourceCalloutMock paymentMock = getStaticMock(200, 'PaymentsMock');

        Map<String, HttpCalloutMock> mocksMap = new Map<String, HttpCalloutMock>();

        mocksMap.put('https://api.example.com/api/2.0/Contacts', contactMock);
        mocksMap.put('https://api.example.com/api/2.0/Invoices', invoiceMock);
        mocksMap.put('https://api.example.com/api/2.0/CreditNotes', creditNoteMock);
        mocksMap.put('https://api.example.com/api/2.0/Payments', paymentMock);

        HttpCalloutMock mocks = new MultiRequestMock(mocksMap);

        return mocks;
    }

    private static StaticResourceCalloutMock getStaticMock(Integer statusCode, String staticResourceName) {

        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();

        mock.setStaticResource(staticResourceName);
        mock.setStatusCode(statusCode);
        mock.setHeader('Content-Type', 'application/json');

        return mock;
    } 
}

And the MultiRequestMock class should throw an error if it trys to do a callout to an endpoint there isn't a mock setup for:

@isTest 
public class MultiRequestMock implements HttpCalloutMock {

    Map<String, HttpCalloutMock> requests;

    public MultiRequestMock(Map<String, HttpCalloutMock> requests) {
        this.requests = requests;
    }

    public HTTPResponse respond(HTTPRequest req) {

        HttpCalloutMock mock = requests.get(req.getEndpoint());

        if (mock != null) {
            return mock.respond(req);
        } 

        throw new MultiRequestMockException('Mock for end point not found: ' + req.getEndpoint());
    }

    public void addRequestMock(String url, HttpCalloutMock mock) {
        requests.put(url, mock);
    }

    public class MultiRequestMockException extends Exception {}
}

But one set of tests that relate to testing a Schedulable class are all still failing.

What have I tried?

I've tried bypassing the Schedulable class and calling the child directly, and it still does not work.

Before

@isTest
public static void test_inactivePerson() 
{  
    Test.setMock(HttpCalloutMock.class, MockFactory.create());

    // arrange
    // create some objects...

    // act
    Test.StartTest();
    System.schedule('Test Schedulable', '0 0 23 * * ?', new StatementSchedulable()); 
    Test.stopTest(); 

    // assert
}

After

@isTest
public static void test_inactivePerson() 
{  
    Test.setMock(HttpCalloutMock.class, MockFactory.create());

    // arrange
    // create some objects...

    // act
    Test.StartTest();
    Statements.generate();
    Test.stopTest(); 

    // assert
}

QUESTION

What else could be caused the error message to be returned?

  • 3
    Try to put some debug logs and check if any trigger is doing a web callout even before setting the HttpCalloutMock in your test method. Or try to set up the HttpCalloutMock at the very first line of the test method. – Naval Sharma Jul 20 '18 at 9:34
  • @NavalSharma Thanks for responding. I don't have any Triggers, and Test.setMock is called at the first line in all unit test. – Robs Jul 20 '18 at 9:37
  • Try to put your Test.setMock after Test.startTest()? Because I doubt it will work in that way. Test.startTest(); Test.setMock(); //Call your scheduler code Test.stopTest(); – Naval Sharma Jul 20 '18 at 9:42
  • Could it by any chance be that the functions in question use a wsdl2apex-generated class to call out to (they need a different mock)? I have been testing this, but haven't been able to reproduce this problem. – rael_kid Jul 20 '18 at 10:50
  • @rael_kid I am not using ` wsdl2apex-generated`. the Call outs are simple XML via HTTP. – Robs Jul 20 '18 at 15:06
0

This issue was caused by test data created within the @testSetup method.

An object was being created with a status which was triggering Process Builder to make the call out.

All of this is running before I was calling on the first line of the test method.

Test.setMock(HttpCalloutMock.class, MockFactory.create());

Respect to @NavalSharma

| improve this answer | |
  • 3
    It might be better to @mention him in the comment thread indicating he correctly identified the issue, and also prompt him to post his guidance as an answer proper. – Adrian Larson Jul 20 '18 at 17:23

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.