+ Start a Discussion
fiona gentryfiona gentry 

Error at Test class "Non static method cannot be referenced from a static context:"

Hi folks,

while calling a service at test class at Line 58 saying
here is test class code 
// Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        
        // Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        HttpResponse res = HerokuBanSync.getBANInfoUpdate('990135742');
        
        // Verify response received contains fake values
        String contentType = res.getHeader('Content-Type');
        System.assert(contentType == 'application/json');
        String actualValue = res.getBody();
        String expectedValue = '{"GSMStackableSOC__c":"false"}';
        System.assertEquals(actualValue, expectedValue);
        System.assertEquals(200, res.getStatusCode());

User-added image
How to resolve the "Non static method cannot be referenced from a static context:" error

Thanks in advance
Fiona




 
Best Answer chosen by fiona gentry
Abdul KhatriAbdul Khatri
Please try this mock
 
@isTest
global class MockHttpResponseFailGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"ban":null}');
        res.setStatusCode(500);
        return res;
    }
}

 

All Answers

Abdul KhatriAbdul Khatri
Hi,

Please use the instance of the HerokuBanSync you created at line 48 like this 
HttpResponse res = basicAcct.getBANInfoUpdate('990135742');
I hope this help

 
fiona gentryfiona gentry
Appreciate your reply @AbdulKhatri ,but i get a different error
User-added image
Abdul KhatriAbdul Khatri
Hi fiona,

Can you check what is your method getBANInforUpdate returns?
fiona gentryfiona gentry
Hi @abdul

this is response while debugging 
11:35:23:837 USER_DEBUG [32]|DEBUG|$$$$$ responseBANInfo:[ban=BAN__c:{AutoPay__c=false, IneligibilityReason__c=null, Last_Samson_Response__c=<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body><getAccountVerificationDataResponse xmlns="http://retail.tmobile.com/sdo"><header><partnerId>SFDC</partnerId><partnerTransactionId>TX-20211011183524019</par

 
Abdul KhatriAbdul Khatri
Can you check the method getBANInforUpdate return HttpResponse, which is what you are expecting?

Can you please send me the method and details? 
fiona gentryfiona gentry
Thank you for helping ,here is the getBANInfoUpdate method 
public with sharing virtual class HerokuBanSync {
    @TestVisible
    public static final Integer MAX_TIMEOUT = 120000;
    
    public BANInfo getBANInfo(String banNumber){
     
        String access_token = TM_APIHandler.generatetoken_SaaS_v6(); // Getting the Proxy token form APIGee
        
        //calling endpoint from custom settings
        //HerokuServices__c herokuServices = HerokuServices__c.getValues('BANUpdate');
        API_Proxy_Endpoints__c herokuServices = API_Proxy_Endpoints__c.getValues('BANUpdate');
        //string endPoint = herokuServices.EndPointUrl__c; 
        String endPoint = herokuServices.API_EndPoint__c;       
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endPoint);
        req.setHeader('banNumber', banNumber);
        req.setMethod('GET');
        req.setTimeout(MAX_TIMEOUT);        
        req.setHeader('Authorization', 'Bearer ' + access_token);
        
        // http call
        Http http = new Http(); 
        new HI_PopTokenGen().buildAuthKey(req);  //Building Auth key for Pop Token.       
        HTTPResponse res = http.send(req);        
        System.debug(res.getStatusCode()); 
        System.debug(res.getStatus());
        if(res.getStatusCode() == 200){            
            BANInfo response = (BANInfo)JSON.deserialize(res.getBody(), BANInfo.class);
            system.debug(res.getBody());
            System.debug('$$$$$ response'+response);            
            return response;            
        }        
        else{  
            System.debug('****Enter into Else *****');
            BANInfo response = new BANInfo();
           
            ban__c ban = new ban__c();
            response.ban = ban;
            response.ban.Last_Samson_Response_DateTime__c = system.now();
            
            response.ban.Last_Samson_Status__c = '' + res.getStatusCode();  
            
            System.debug('response from samson'+ response);
            return response;    
        }        
       // return null;        
    }

    public void getBANInfoUpdate(String banNumber){
        
        BANInfo banResp = getBANInfo(banNumber);
        if(banResp != null){
            system.debug('banResp id'+banResp);
            banResp.ban.BAN_Number__c = banNumber;
            banResp.updateRecords();
        }      
    }
    
    public class BANInfo{
        public BAN__c ban;

        public void updateRecords(){
            SavePoint sp = Database.setSavePoint();
            
            system.debug('banInfo ss'+ban);
            
            try{
                
                Database.upsert(ban, BAN__c.BAN_Number__c, true);
            }
            catch(DMLException e){
                Database.rollback(sp);
                System.debug(e.getStackTraceString());
            }
        }
    }    
}

Also expected response from the method getBANInfoUpdate is 
13:22:56:584 USER_DEBUG [31]|DEBUG|{"ban":{"GSM_Data_Stackable__c":false,"Billing_Address_Classification__c":"STREET_ADDRESS","TaxIndicator__c":"TE","maximumCreditLimit__c":4320.0,"Sub_Market__c":"MIM","GSMStackableSOC__c":false,"Delinquent__c":true,"Bill_Cycle_Code__c":"4","Bill_Due_Date__c":"2014-06-27","Cancelled_BAN__c":false,"MI_Deposit_Amount_Reduced__c":&qu


 
Abdul KhatriAbdul Khatri
Hi fiona,

Thanks for sharing the code. This gave me huge clarify. Since you haven't shard the test class but this is what you need to do in your test class

Create a mock class which you may already have to this (if need change the setBody as per your need)
global class MockHttpResponseGenerator implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"ban":{"GSM_Data_Stackable__c":false,"Billing_Address_Classification__c":"STREET_ADDRESS","TaxIndicator__c":"TE","maximumCreditLimit__c":4320.0,"Sub_Market__c":"MIM","GSMStackableSOC__c":false,"Delinquent__c":true,"Bill_Cycle_Code__c":"4","Bill_Due_Date__c":"2014-06-27","Cancelled_BAN__c":false,"MI_Deposit_Amount_Reduced__c":""}}');
        res.setStatusCode(200);
        return res;
    }
}
In the test class please 
change this
// Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        HttpResponse res = HerokuBanSync.getBANInfoUpdate('990135742');
        
        // Verify response received contains fake values
        String contentType = res.getHeader('Content-Type');
        System.assert(contentType == 'application/json');
        String actualValue = res.getBody();
        String expectedValue = '{"GSMStackableSOC__c":"false"}';
        System.assertEquals(actualValue, expectedValue);
        System.assertEquals(200, res.getStatusCode());

to this. You can add more fields in SOQL and then assert them with the fake response you get from the mock class.
// Call method to test. 
// This causes a fake response to be sent 
// from the class that implements HttpCalloutMock. 
basicAcct.getBANInfoUpdate('990135742');

// Verify response received contains fake values
BAN__c banAfterUpdate = [SELECT Id, TaxIndicator__c FROM BAN__c];
system.assert(banAfterUpdate.GSM_Data_Stackable__c == false);

Let me know if this help. Let me know if you need more assistance with apex.
fiona gentryfiona gentry
This is so so great ,one last question ,how do i test the else block of apex class ,it still shows not covered 
else{  
            System.debug('****Enter into Else *****');
            BANInfo response = new BANInfo();
           
            ban__c ban = new ban__c();
            response.ban = ban;
            response.ban.Last_Samson_Response_DateTime__c = system.now();
            
            response.ban.Last_Samson_Status__c = '' + res.getStatusCode();  
            
            System.debug('response from samson'+ response);
            return response;    
        }        
       // return null;        
    }
Abdul KhatriAbdul Khatri
Hi,

Good I am glad it is helping you.

Create another moke fail kind of like this.
global class MockHttpResponseFailGenerator implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('');
        res.setStatusCode(500);
        return res;
    }
}

create another testmethod and put this in there
Test.setMock(HttpCalloutMock.class, new MockHttpResponseFailGenerator());
        
// Call method to test. 
// This causes a fake response to be sent 
// from the class that implements HttpCalloutMock. 
basicAcct.getBANInfoUpdate('990135742'); 

// Verify response received contains fake values 
BAN__c banAfterUpdate = [SELECT Id, TaxIndicator__c FROM BAN__c]; system.assert(banAfterUpdate.Last_Samson_Status__c.contains('500'));

Let me know, if this help.
lso let me know if you need to learn Apex.
fiona gentryfiona gentry
Created a new test method ,this time got error  as below
System.JSONException: No content to map to Object due to end of input



here is class 
Test.setMock(HttpCalloutMock.class, new MockHttpResponseFailGenerator());
        
        
        // Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        Test.starttest();
        HerokuBanSync basicAcct = new HerokuBanSync();
        basicAcct.getBANInfoUpdate('110005906');
        
        BAN__c banAfterUpdate = [SELECT Id,Last_Samson_Status__c FROM BAN__c];
        system.assert(banAfterUpdate.Last_Samson_Status__c.contains('500'));
        
        Test.stoptest();
here failmock generator class
 
@isTest
global class MockHttpResponseFailGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('');
        res.setStatusCode(500);
        return res;
    }
}


 
Abdul KhatriAbdul Khatri
Please try this mock
 
@isTest
global class MockHttpResponseFailGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"ban":null}');
        res.setStatusCode(500);
        return res;
    }
}

 
This was selected as the best answer
fiona gentryfiona gentry
Worked like a charm ,Thank you so much
Abdul KhatriAbdul Khatri
Let me know if you need help with anything