0

恐怕有点卡在另一个上,我正在尝试为批量 APEX 类编写单元测试。

该类有一个对 google api 的标注,所以我创建了一个静态资源,我通过一个模拟输入它,所以我可以完成处理返回的 JSON 的测试。但是由于某种原因,响应总是空的。

现在非常奇怪的是,如果我在之前的 @future 调用中使用完全相同的标注/JSON 代码和相同的模拟代码,那么它确实返回正常。

这是课程:

global class mileage_bulk implements Database.Batchable<sObject>,
  Database.AllowsCallouts
{
global Database.QueryLocator start(Database.BatchableContext BC)
{
String query = 'SELECT Id,Name,Amount,R2_Job_Ref__c,R2_Shipping_Post_Code__c,Shipping_Postcode_2__c FROM Opportunity WHERE R2_Shipping_Post_Code__c != null';
return Database.getQueryLocator(query);
//system.debug('Executing'+query);
}

global void execute(Database.BatchableContext BC, List<Opportunity> scope)
{
system.debug(scope);
for(Opportunity a : scope)
{

    String startPostcode = null;
    startPostcode = EncodingUtil.urlEncode('HP27DU', 'UTF-8');
    String endPostcode = null;
    String endPostcodeEncoded = null;
    if (a.R2_Shipping_Post_Code__c != null){
    endPostcode =   a.R2_Shipping_Post_Code__c;
    Pattern nonWordChar = Pattern.compile('[^\\w]');
    endPostcode = nonWordChar.matcher(endPostcode).replaceAll('');
    endPostcodeEncoded =   EncodingUtil.urlEncode(endPostcode, 'UTF-8');
        }   
    Double totalDistanceMeter = null;
    Integer totalDistanceMile = null;
   String responseBody = null;
   Boolean firstRecord = false;

    String ukPrefix = 'UKH';
    if (a.R2_Job_Ref__c != null){    
    if ((a.R2_Job_Ref__c).toLowerCase().contains(ukPrefix.toLowerCase())){
    system.debug('Is Hemel Job');
    startPostcode = EncodingUtil.urlEncode('HP27DU', 'UTF-8');
    } else {
    system.debug('Is Bromsgrove Job');
    startPostcode = EncodingUtil.urlEncode('B604AD', 'UTF-8');
    }
    }

    // build callout
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://maps.googleapis.com/maps/api/directions/json?origin='+startPostcode+'&destination='+endPostcodeEncoded+'&units=imperial&sensor=false');
    req.setMethod('GET');
    req.setTimeout(60000);
    system.debug('request follows');
    system.debug(req);

try{  
        // callout
        HttpResponse res = h.send(req);

        // parse coordinates from response

        JSONParser parser = JSON.createParser(res.getBody());

        responseBody = res.getBody();
        system.debug(responseBody);

        while (parser.nextToken() != null) {
            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && 
                (parser.getText() == 'distance')){
                   parser.nextToken(); // object start
                   while (parser.nextToken() != JSONToken.END_OBJECT){
                       String txt = parser.getText();
                       parser.nextToken();
                       //system.debug(parser.nextToken());
                       //system.debug(txt);
                       if (firstRecord == false){
                       //if (txt == 'text'){
                           //totalDistanceMile = parser.getText();
                           system.debug(parser.getText());
                       //}
                       if (txt == 'value'){
                           totalDistanceMeter = parser.getDoubleValue();
                           double inches = totalDistanceMeter*39.3701;
                           totalDistanceMile = (integer)inches/63360;
                           system.debug(parser.getText());
                           firstRecord = true;
                       }
                       }
                   }

            }
        }


    } catch (Exception e) {
    }

//system.debug(accountId);
    system.debug(a);
    system.debug(endPostcodeEncoded);
    system.debug(totalDistanceMeter);
    system.debug(totalDistanceMile);

        // update coordinates if we get back 
        if (totalDistanceMile != null){
        system.debug('Entering Function to Update Object');
            a.DistanceM__c = totalDistanceMile;
            a.Shipping_Postcode_2__c = a.R2_Shipping_Post_Code__c;
            //update a;        
        }  
}
update scope;
}


global void finish(Database.BatchableContext BC)
{
}
}

这是测试类;

@isTest
private class mileage_bulk_tests{

static testMethod void myUnitTest() {
     Opportunity opp1 = new Opportunity(name = 'Google Test Opportunity',R2_Job_Ref__c = 'UKH12345',R2_Shipping_Post_Code__c = 'AL35QW',StageName = 'qualified',CloseDate = Date.today());
 insert opp1;
 Opportunity opp2 = new Opportunity(name = 'Google Test Opportunity 2',StageName = 'qualified',CloseDate = Date.today());
 insert opp2;
 Opportunity opp3 = new Opportunity(name = 'Google Test Opportunity 3',R2_Job_Ref__c = 'UKB56789',R2_Shipping_Post_Code__c = 'AL35QW',StageName = 'qualified',CloseDate = Date.today());
insert opp3;


StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
mock.setStaticResource('googleMapsJSON');
mock.setStatusCode(200); // Or other appropriate HTTP status code
mock.setHeader('Content-Type', 'application/json'); // Or other appropriate MIME type like application/xml

//Set the mock callout mode
Test.setMock(HttpCalloutMock.class, mock);

system.debug(opp1);
system.debug(opp1.id);

//Call the method that performs the callout
Test.startTest();
mileage_bulk b = new mileage_bulk();
database.executeBatch((b), 10);
Test.stopTest();
    }
}

非常感谢帮助!

谢谢

加雷斯

4

1 回答 1

2
  1. 不确定“googleMapsJSON”是什么样的,也许你可以为我们发帖。
  2. 假设您的模拟资源格式正确,请确保文件扩展名为“.json”并使用 UTF-8 编码保存。

    如果 #2 不起作用,您应该尝试将资源另存为 .txt - 我之前遇到过它需要纯文本资源但预期的应用程序/json 内容类型

  3. 确保您提供的资源名称字符串与资源名称的大小写相同。它区分大小写。

  4. 您是否在命名空间包环境中进行开发?如果是这样,请尝试将命名空间添加到资源名称。

否则,您的代码乍一看还不错。

于 2013-09-14T07:19:08.183 回答