[SalesForce] HTTP Callout Test Error

I'm trying to push some code from one of our sandboxes to production.

Class:

public class CloudtoDevOps {    
    @future (callout=true)
    public static void sendNotification(String ClientID, String Name, String Status, String Datacenter, Decimal Users, Decimal Storage) {

        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        JSONGenerator gen = JSON.createGenerator(true);

        gen.writeStartObject();
        gen.writeStringField('client_id', ClientID);
        gen.writeStringField('client_full_name', Name);
        gen.writeStringField('status', Status);
        gen.writeStringField('hosted_datacenter', Datacenter);
        gen.writeNumberField('number_of_licenses', Users);
        gen.writeNumberField('storage_amount_in_gb', Storage);
        gen.writeEndObject();

        String jsonString = gen.getAsString();

        req.setEndpoint('URL');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json;charset=UTF-8');
        req.setBody(jsonString);

        try {
            res = http.send(req);
        } catch(System.CalloutException e) {
            System.debug('Callout error: '+ e);
            System.debug(res.toString());
        }
    }
}

Trigger:

trigger CloudtoDev on Cloud_Environment__c (after insert, after update) {
    for (Cloud_Environment__c c: Trigger.new) {
        CloudtoDevOps.SendNotification(c.Client_ID__c, c.Name, c.Status__c, c.Data_Center__c, c.Users__c, c.Storage_Amount__c);
    }
}

Mock Callout:

@isTest
global class CloudtoDevOpsMock implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        System.assertEquals('URL', req.getEndpoint());
        System.assertEquals('POST', req.getMethod());

        JSONGenerator gen = JSON.createGenerator(true);

        gen.writeStartObject();
        gen.writeStringField('client_id', 'abcabc');
        gen.writeStringField('client_full_name', 'Test Account');
        gen.writeStringField('status', 'Live');
        gen.writeStringField('hosted_datacenter', 'CH3');
        gen.writeNumberField('number_of_licenses', 100);
        gen.writeNumberField('storage_amount_in_gb', 200);
        gen.writeEndObject();
        String jsonString = gen.getAsString();

        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json;charset=UTF-8');
        res.setBody(jsonString);
        res.setStatusCode(200);
        return res;
    }
}

Test Class:

@isTest
public class CloudtoDevOpsTest {
    @isTest public static void testCallout() {
        System.test.setMock(System.HttpCalloutMock.class, new CloudtoDevOpsMock());
        HttpResponse response = CloudtoDevOps.sendNotification('abcab', 'Test Account', 'Live', 'CH3', 100, 200);
        String contentType = response.getHeader('Content-Type');
        System.assert(contentType == 'application/json;charset=UTF-8');
        String actualResultValue = response.getBody();
        String expectedResultValue = '{"client_id": "abcab","client_full_name": "Test Account","status": "Live","hosted_datacenter": "CH3","number_of_licenses": 100,  "storage_amount_in_gb": 200}';
        System.assertEquals(actualResultValue, expectedResultValue);
        System.assertEquals(200, response.getStatusCode());
        System.debug(actualResultValue);
        System.debug(expectedResultValue);
    }
}

I'm getting the following error on line 5 of the test class: Illegal assignment from void to System.HttpResponse

I've test the class/trigger using requestb.in and everything works as I would expect but I can't push to production because code coverage is coming back as 0%.

Best Answer

Your method doesn't return any value, since its return type is void. So you cannot make any direct assertions on your HttpResponse. It wouldn't make sense to do so anyway, since the response is mocked. What you need to test is how your code handles a given response. Or in this case, since you don't do any processing of the response, just check that a callout is consumed.

Test.startTest();
    // call method
    Integer callouts = Limits.getCallouts();
Test.stopTest();

system.assertEquals(1, callouts, 'The method should make a callout');

If you want to make assertions about what headers you set on your request, you could certainly cache those in your mock.

@IsTest
public class MyMock
{
    static Map<String, String> headers = new Map<String, String>();

    public HttpResponse respond(HttpRequest request)
    {
        headers.clear();
        headers.put('Content-Type', request.getHeader('Content-Type'));
        // etc.
    }
}

Then, in your test, you could assert on which headers were included with the most recent request:

Test.startTest();
    // call method
    Integer callouts = Limits.getCallouts();
Test.stopTest();

system.assertEquals(1, callouts, 'The method should make a callout');
system.assertEquals(expectedContentType, MyMock.headers.get('Content-Type'),
    'The Content-Type header should be set');
Related Topic