Questa callout è di tipo rest e chiama un endpoint per aggiornarnare l’inventario dei prodotti a disposizione di una società.
In questo esempio è utilizzata anche una wrapper class perchè il risultato della chiamata da campi che devono essere mappati con quelli dell’oggetto “prodotti” in Salesforce
public with sharing class WarehouseCalloutService {
private static final String WAREHOUSE_URL = 'https://th-superbadge-apex.herokuapp.com/equipment';
// complete this method to make the callout (using @future) to the
// REST endpoint and update equipment on hand.
@future(callout=true)
public static void runWarehouseEquipmentSync(){ // questo dovrebbe girare dal trigger MaintenanceRequest. e utilizzare la lista dei case interessati List<Id> equip
Http h = new Http();
HttpRequest rq = new HttpRequest();
rq.setEndpoint(WAREHOUSE_URL);
rq.setMethod('GET');
rq.setCompressed(true);
HttpResponse res = h.send(rq);
List<Product2> listaprodotti = new List<Product2>();
if(res.getStatusCode() == 200){
List<Json2Apex> lstOfEquipments = (List<Json2Apex>) JSON.deserialize(res.getBody(), List<Json2Apex>.class);
for(Json2Apex inst:lstOfEquipments){
Product2 prod = new Product2();
prod.Cost__c = inst.cost;
prod.Lifespan_Months__c = inst.lifespan;
prod.Maintenance_Cycle__c = inst.maintenanceperiod;
prod.Name = inst.name;
prod.Current_Inventory__c = inst.quantity;
prod.Replacement_Part__c = inst.replacement;
prod.Warehouse_SKU__c = inst.sku;
listaprodotti.add(prod);
}
if(listaprodotti != null && listaprodotti.size() > 0){
UPSERT listaprodotti Warehouse_SKU__c;
}
}else{
System.debug('Errore di connessione al endpoint');
}
}
// wrapper class
private class Json2Apex{
private String id;
private Integer cost;
private Integer lifespan;
private Integer maintenanceperiod;
private String name;
private Integer quantity;
private Boolean replacement;
private String sku;
}
}
Testare una callout rest
Per testare una callout rest bisogna creare una classe mock e una classe di test
Iniziamo dalla classe mock
@isTest
global class WarehouseCalloutServiceMock implements HttpCalloutMock {
// Implement this interface method
global HTTPResponse respond(HTTPRequest request) {
// Create a fake response
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setBody('[{"_id": "55d66226726b611100aaf741","replacement": false,"quantity": 5,"name": "Generator 1000 kW","maintenanceperiod": 365,"lifespan": 120,"cost": 5000,"sku": "100003"},{"_id": "55d66226726b611100aaf742","replacement": false,"quantity": 5,"name": "Cooling Fan","maintenanceperiod": 365,"lifespan": 120,"cost": 5000,"sku": "100004"}]');
response.setStatusCode(200);
return response;
}
}
La classe mock simula la chiamata all’esterno
Mentre la classe di test invoca sia la mock si la callout da testare
@isTest
private class WarehouseCalloutServiceTest {
@isTest static void testGetCallout() {
Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());
Test.startTest();
WarehouseCalloutService.runWarehouseEquipmentSync();
Test.stopTest();
Product2 p = [select Name from product2 where Warehouse_SKU__c = '100003' ];
System.assertEquals(p.name, 'Generator 1000 kW');
}
}
Esempio da documentazione ufficiale
Classe Mock che implementa diverse interfacce
@isTest
global class DiscardCalloutMock implements WebServiceMock {
global void doInvoke(
Object stub,
Object request,
Map<String, Object> response,
String endpoint,
String soapAction,
String requestName,
String responseNS,
String responseName,
String responseType) {
// Create response element from the autogenerated class.
// Populate response element.
// Add response element to the response parameter, as follows:
response.put('response_x', getResponseKO());
}
public static [Tipo] getResponseKO(){
[Tipo] calloutResponse = new [Tipo]();
wrts_prcgvr.MRR_1_0.Response response = new wrts_prcgvr.MRR_1_0.Response();
response.code = 'KO';
response.description = 'Case Transition not found AsyncResponse Current Phase :AL010';
response.header = new [Tipo]();
response.header.fields = new List<[Tipo]>{
buildField('flowCode', 'string', 'A01_0150'),
buildField('status', 'string', '0'),
buildField('category', 'string', 'AsyncResponse')
};
response.header.requestId = 'AGIwXHMf51tba6bmjMVMcHRb7-gS';
response.header.requestTimestamp = '2022-03-15 17:59:41';
response.header.requestType = 'Richiesta Aggiornamento Case';
List<wrts_prcgvr.MRR_1_0.Response> rList = new List<wrts_prcgvr.MRR_1_0.Response>();
rList.add(response);
calloutResponse.responses = rList;
return calloutResponse;
}
public static [Tipo](String name, String type, String value){
[Tipo] = new [Tipo].Field();
field.name = name;
field.fieldType = type;
field.value = value;
return field;
}
}