0

I have System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set and I don't know how to fix it.

Callout:

public class Callout {
public List<Tool__c> toolsList;
public HttpResponse responseService;

public HttpRequest createRequestForToken(){
    HttpRequest ourRequest = new HttpRequest();
    ourRequest.setBody(myTokenString);
    ourRequest.setMethod('GET');
    ourRequest.setEndpoint('https://my.salesforce.com/services/oauth2/token');
    return ourRequest;
}

public class getToken{
    public String WEB_TOKEN{get;set;}
}

public HttpRequest createRequestForService(String token){
    HttpRequest finalRequest = new HttpRequest();
    finalRequest.setHeader('Authorization','Bearer ' + token);
    finalRequest.setHeader('Content-Type','application/json');
    finalRequest.setHeader('accept','application/json');
    finalRequest.setMethod('GET');
    finalRequest.setEndpoint('https://my.salesforce.com/services/apexrest/endpoint');
    return finalRequest;
}

public List<Tool__c> getCalloutResponseContents() {
    Http ourHttp = new Http();
    HttpRequest requestForToken = createRequestForToken();
    HttpResponse responseToken = ourHttp.send(requestForToken);
    getToken objAuthenticationInfo = (getToken)JSON.deserialize(responseToken.getbody(), getToken.class);

    if(objAuthenticationInfo.WEB_TOKEN != null) {
        HttpRequest requestForService = createRequestForService(objAuthenticationInfo.WEB_TOKEN);
        responseService = ourHttp.send(requestForService);
        //System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set:
        toolsList = (List<Tool__c>)JSON.deserialize(responseService.getBody(), List<Tool__c>.class);

        for(Tool__c t : toolsList) {
            t.Id = null;
        }
        return toolsList;
    }
    return null;
}
}

Mock:

@isTest
global class MyMock implements HttpCalloutMock {

String token;

public MyMock(String token) {
    this.token = token;
}

global HTTPResponse respond(HTTPRequest request) {
    HttpResponse response = new HttpResponse();
    response.setHeader('Content-Type', 'application/json');
    String serialized;
    if(request.getEndpoint().contains('services/oauth2/token')) {
        serialized = '{"'+ token +'":"FAKE-WEB-TOKEN"}';
    } else {
        serialized = '{"Name":"OurName"}';
    }
    response.setBody(serialized);
    return response;
}
}

Test:

@isTest
private class CalloutTest {

static String getTokenBody(){
    String consumerKey = '234234234';
    String consumerSecret = '678678678';
    String username = '[email protected]';
    String password = '12312321213';
    String request = 'grant_type=password&client_id=' + consumerKey +'&client_secret=' + consumerSecret +
                     '&username=' + username + '&password='+password;
    return request;
}

@isTest
static void testGetCallout() {
    Callout callout = new Callout();

    String request = myTokenString;
    Test.setMock(HttpCalloutMock.class, new MyMock('WEB_TOKEN'));

    Test.startTest();
    //System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set:
    List<Tool__c> toolsList = callout.getCalloutResponseContents();
    HttpResponse response = callout.responseService;
    Test.stopTest();

    String contentType = response.getHeader('Content-Type');
    String actualValue = response.getBody();
    String expectedValue = '{"Name":"OurName"}';

    System.assert(contentType == 'application/json');
    System.assertEquals(actualValue, expectedValue);
}
}

1 Answer 1

4

Your mock needs to return a list for the other endpoint:

if(request.getEndpoint().contains('services/oauth2/token')) {
    serialized = '{"'+ token +'":"FAKE-WEB-TOKEN"}';
} else {
    serialized = '[{"attributes":{"sobjectType":"Tool__c",...},{...},...]';
}

You must log in to answer this question.

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