function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Valentin F.Valentin F. 

Unable to test callout into future method

Hello everybody,

I need to test a callout situated in a @future method.
I used the 'Test.setMock(HttpCalloutMock.class, new AppelAPIMock());' to do it but I am not able to test XmlNode.

Here is an example to make it easier for you to understand :
 

@future(callout=true)
...
//Method realizing the callout
HttpResponse resp = appelDpd.getTrackingDPD(xmlBody);
            String responseBody = resp.getBody();
            if(resp.getStatusCode() == 200) {
                Dom.Document xmlD = new Dom.Document();
                xmlD.load(responseBody);

 //All this part is not supported by tests method               
                Dom.XmlNode root = xmlD.getRootElement();
                Dom.XmlNode body = root.getChildElement('Body',null);
                Dom.XmlNode trace = body.getChildElement('getShipmentTraceResponse', null);
                Dom.XmlNode traceResult = trace.getChildElement('getShipmentTraceResult', null);
                
                for(Dom.XmlNode node : traceResult.getChildElements()) {
if(node.getName() == 'ShippingDate' && node != null && node.getText().trim() != ''){}
Best Answer chosen by Valentin F.
Valentin F.Valentin F.
Well I know why it didn't come inside when I copy/paste this code
I finished xml string by '</soap:Body>' and '</soap:Envelope>' and not  '</soap12:Body>' and '</soap12:Envelope>'.
Stupid error ...

But it stil not going into if/else, essentially when I check for statusNumber (here even the 308 statusNumber is not covered :
if(statusNum <= 8) { ... }
else if(statusNum >= 10 && statusNum <= 37 || statusNum == 44 || statusNum == 120 ||) {...}
else if(statusNum == 308) {...}

 

All Answers

MKRMKR
Hi,

Have you surrounded the callout for the future method in test class with Test.startTest() and Test.stopTest()? And does your AppelAPIMock set valid response body and response code as 200?

Regards,
MKR
Valentin F.Valentin F.
Hi MKR,
I did in my test class :
Test.startTest();
        	Test.setMock(HttpCalloutMock.class, new AppelAPIMock());
Test.stopTest();
AppelAPIMock.apxc
global with sharing class AppelAPIMock implements HTTPCalloutMock{
    global HTTPResponse respond(HTTPRequest req){
        HttpResponse res = new HTTPResponse();
        res.setHeader('Content-Type', 'text/xml');
        res.setBody('<?xml version="1.0" encoding="utf-8"?>' +
        	'<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
        		'<soap12:Body>' +
            		'<getShipmentTraceResponse xmlns="http://www.cargonet.software/">' +
            			'<getShipmentTraceResult>' +
                            '<ShippingDate>02.08.2019</ShippingDate>' +
                            '<DeliveryDate>05.08.2019</DeliveryDate>' + 
                            '<Weight>0</Weight>' + 
                            '<Traces>' + 
                                '<clsTrace>' +
                                    '<StatusNumber>308</StatusNumber>' +
                                    '<StatusDescription>En attente de vos instructions</StatusDescription>' + 
                                '</clsTrace>' + 
                            '</Traces>' + 
                    	'</getShipmentTraceResult>' +  
                 	'</getShipmentTraceResponse>' + 
               	'</soap:Body>' + 
            '</soap:Envelope>');
        res.setStatusCode(200);
        return res;
    }
}
I wrote the same nodes as expected in my class.

 
Valentin F.Valentin F.
Well I know why it didn't come inside when I copy/paste this code
I finished xml string by '</soap:Body>' and '</soap:Envelope>' and not  '</soap12:Body>' and '</soap12:Envelope>'.
Stupid error ...

But it stil not going into if/else, essentially when I check for statusNumber (here even the 308 statusNumber is not covered :
if(statusNum <= 8) { ... }
else if(statusNum >= 10 && statusNum <= 37 || statusNum == 44 || statusNum == 120 ||) {...}
else if(statusNum == 308) {...}

 
This was selected as the best answer
Deepali KulshresthaDeepali Kulshrestha
Hi Valentin,

For the test class of future callout method, you have to create a callout Mock class which implements the HttpCalloutMock, because Methods defined as TestMethod do not support Web service callouts and you are doing Web service callouts, so you have to create a fake callout response.

for creating a HttpCalloutMock class please go through the given link as it may help you in solving your problem.
-https://www.thephani.com/test-classes-for-future-methods-callout-true/

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Deepali Kulshrestha

 
MKRMKR
Hi,

Please ensure to include namespace in the getChildElement calls like this:
Dom.XmlNode root = xmlD.getRootElement();
Dom.XmlNode body = root.getChildElement('Body','http://www.w3.org/2003/05/soap-envelope');
Dom.XmlNode trace = body.getChildElement('getShipmentTraceResponse', 'http://www.cargonet.software/');
Dom.XmlNode traceResult = trace.getChildElement('getShipmentTraceResult', 'http://www.cargonet.software/');
Regards,
MKR