7

In My Method making two callouts in a single transaction

  1. Get Access Token For that API --> GetAccessToken
  2. Execute Payment

When i ran the test class getting following error 08:50:00:839 FATAL_ERROR System.NullPointerException: Argument 2 cannot be null. in this code request.setHeader('Authorization', accessTokenValue);

In my Mockup Response I am setting Only on Execute Payment, Can we mock the Access Token API in the Same method. Since mock class only execute Payment response, not able to do the access token call so accessTokenValue is set as NULL.

Is there any way we can have multiple mock in a single test class method. Guide me on this. Thank You

Method:

 @AuraEnabled 
    public static boolean executepaymentbupayid(string payPalPayId , string payerid, Id familyrecId, string internalTransactionId){
        
        // string authorisation;
        string accessTokenValue;
        List<AggregateResult> aggr = [SELECT Service_Center__r.Client_ID__c,  Service_Center__r.Secret__c 
                                      ,Service_Center__r.PayPal_API__c
                                      FROM invoice__c WHERE   Student_Family__c=:familyrecId
                                      Group by Service_Center__r.Client_ID__c,  Service_Center__r.Secret__c, Service_Center__r.PayPal_API__c ];
        
        HttpResponse response = getPaypalAccessToken.GetAccessToken(String.valueOf(aggr[0].get('Client_ID__c')),String.valueOf(aggr[0].get('Secret__c')), String.valueOf(aggr[0].get('PayPal_API__c'))); 


        Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        if (response.getStatusCode() == 200) {           
            System.debug('results' + results.get('access_token'));
            System.debug('results' + results.get('token_type'));
            string tokentype = String.valueof(results.get('token_type'));
            string accesstoken = String.valueof(results.get('access_token'));        
            accessTokenValue = tokentype + ' ' + accesstoken;
        }
        
   
        
        executePayment executePaymentWrapper = new executePayment(); 
        executePaymentWrapper.payerid = payerid;
        String myJSON = JSON.serialize(executePaymentWrapper);
        String jsonReplacedString;
        jsonReplacedString = myJSON.replace('payerid', 'payer_id');
        
        
        string endpoint;       
        endpoint = System.Label.PayPal_Live_Execute_Payment + payPalPayId + '/execute';
     
        
        http http = new http();
        httpRequest request = new httpRequest();
        request.setMethod('POST');
        request.setEndpoint(endpoint);
        request.setHeader('Content-Type', 'application/json');
        request.setHeader('Authorization', accessTokenValue);
        request.setBody(jsonReplacedString);
        httpResponse res = http.send(request);      
        if (Res.getStatusCode() == 200){
            boolean updatePaymentReceived = paymentReceivedUpdate(familyrecId, internalTransactionId);            
            If(updatePaymentReceived){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }        
    }

Test Method

    @isTest
    public static void executepaymentbupayidTest(){
        Map <string,id> testData = TestDataFactory.CreateTestDate();  
        ID familyId = TestData.get('FamilyID');
        string payPalPayId ='PAYID-L43IDSI2C58062971907464F';
        string payerid ='SDV9S3QZQQPM4';
        string internalTransactionId = 'internalTransactionId';        
        test.startTest(); 
        Test.setMock(HttpCalloutMock.class, new ExecutepaymentbupayidMock()); 
        Boolean returnValue = Invoice.executepaymentbupayid(payPalPayId, payerid, familyId, internalTransactionId);
        test.stopTest();
    }

Mock Response:

@istest
public class ExecutepaymentbupayidMock implements HttpCalloutMock{
    
    public HTTPResponse respond(HTTPRequest request) {
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"id": "PAYID-L43IDSI2C58062971907464F","intent": "sale","state": "approved","cart": "8YT815237T955371T","payer": {"payment_method": "paypal","status": "VERIFIED","payer_info": {"email": "[email protected]","first_name": "Safari","last_name": "Individual","payer_id": "SDV9S3QZQQPM4","shipping_address": {"recipient_name": "Brian Robinson","line1": "4th Floor","line2": "Unit #34","city": "San Jose","state": "CA","postal_code": "95131","country_code": "US"},"phone": "4089285295","country_code": "US"}},"transactions": [{"amount": {"total": "95.00","currency": "USD","details": {"subtotal": "95.00","shipping": "0.00","insurance": "0.00","handling_fee": "0.00","shipping_discount": "0.00"}},"payee": {"merchant_id": "JKHMJ249QW9TU","email": "[email protected]"},"description": "Invoice Number - 0401","custom": "gE9SyW893fA2bMVDUwVosLpM1gKxqkx0%2B3MqYXpEDjM841djbcYnoN9%2BIgqgdass","invoice_number": "401","item_list": {"items": [{"name": "Invoice Number - 0401","description": "Session 2 (weeks of June 29-July 2 and July 6-9)","price": "95.00","currency": "USD","tax": "0.00","quantity": 1}],"shipping_address": {"recipient_name": "Brian Robinson","line1": "4th Floor","line2": "Unit #34","city": "San Jose","state": "CA","postal_code": "95131","country_code": "US"}},"related_resources": [{"sale": {"id": "2T59651963103743W","state": "completed","amount": {"total": "95.00","currency": "USD","details": {"subtotal": "95.00","shipping": "0.00","insurance": "0.00","handling_fee": "0.00","shipping_discount": "0.00"}},"payment_mode": "INSTANT_TRANSFER","protection_eligibility": "ELIGIBLE","protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE","transaction_fee": {"value": "3.06","currency": "USD"},"parent_payment": "PAYID-L43IDSI2C58062971907464F","create_time": "2020-08-14T12:39:00Z","update_time": "2020-08-14T12:39:00Z","links": [{"href": "https://api.sandbox.paypal.com/v1/payments/sale/2T59651963103743W","rel": "self","method": "GET"},{"href": "https://api.sandbox.paypal.com/v1/payments/sale/2T59651963103743W/refund","rel": "refund","method": "POST"},{"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-L43IDSI2C58062971907464F","rel": "parent_payment","method": "GET"}]}}]}],"create_time": "2020-08-14T12:21:29Z","update_time": "2020-08-14T12:39:00Z","links": [{"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-L43IDSI2C58062971907464F","rel": "self","method": "GET"}]}');
        response.setStatusCode(201);
        return response; 
    }
}

1 Answer 1

14

Yes, you can, using either of two techniques.

Your HttpCalloutMock's respond() method can inspect its inbound HttpRequest, and construct a different response based on which endpoint is being called, the parameters passed, etc. This allows you to write a single class that returns responses for multiple callouts made in sequence in your code under test.

Alternately, you can choose to use the MultiStaticResourceCalloutMock class. This class allows you to store response bodies in Static Resources within your application, and to configure the Mock for multiple endpoints by calling setStaticResource() once per endpoint to which you wish the Mock to respond. This can save you writing some boilerplate code, if you don't mind storing your responses in Static Resources rather than constructing them in code.

1
  • Thank You, I implemented the first techniques and it's working. Commented Aug 18, 2020 at 3:42

You must log in to answer this question.

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