Apex为什么标准控制器在创建控制器时没有设置当前页面(单元测试)

时间:2012-08-15 20:23:12

标签: salesforce apex-code visualforce force.com

在Apex Unit测试中,为什么MyConrtoller myCont = new MyController(StandardContoller);呼叫设置当前页面?

例如,如果我有这个页面:

<apex:page standardController="DB_Object__c" extensions="MyExtension">
  <apex:form id="detail_list">
    <apex:detail />
    <apex:actionStatus id="readStatus">
    <apex:facet name="start">
        Loading, please wait...
   </apex:facet>
    <apex:facet name="stop"><apex:outputPanel >
        <apex:commandButton action="{!readData}"
            value="Update Data"
            rerender="detail_list"
            status="readStatus"/>
        {!remainingRecords}</apex:outputPanel>
    </apex:facet>
   </apex:actionStatus>
   </apex:form>
</apex:page> 

如果我的单元测试创​​建了这个:

DB_Object__c dbObj = new DB_Object__c();
dbObj.Name = 'test';
dbObj.Setting = 'aSetting';
insert dbObj;
Test.setCurrentPageReference(Page.Demo);
ApexPages.StandardController sc = new ApexPages.StandardController(dbObj);
MyExtension myExt = new MyExtension(sc);

为什么ApexPages.currentPage().getParameters().get('id');会失败?我必须这样做:

ApexPages.currentPage().getParameters().put('id',dbObj.id);

如果dbObjStandardController没有任何意义,那么将{{1}}传递给{{1}}有什么意义?您是否在空白对象中发送的意图和扩展使用此对象?标准控制器和单元测试似乎没有很多文档...

谢谢!

3 个答案:

答案 0 :(得分:2)

在测试场景中解决这个问题的一种方法是:

// at first you have to create the object
DB_Object__c dbObj = new DB_Object__c();
dbObj.Name = 'test';
dbObj.Setting = 'aSetting';
insert dbObj;

// then you'd call the vf page with the id query paramter
Test.setCurrentPageReference(Page.Demo);
ApexPages.currentPage().getParameters().put('id', dbObj.Id);
dbObj = [Select All, Fields, You, Need From DB_Object__c Where Id = :ApexPages.currentPage().getParamters().get('id')];

// then the StandardController & controller extension get initiated
ApexPages.StandardController sc = new ApexPages.StandardController(dbObj);
MyExtension myExt = new MyExtension(sc);

现在问你为什么getParameters().get('id')会失败?您可以启动没有记录ID的StandardController,它会为您提供新记录,并在您使用默认的save PageReference时自动插入记录。

答案 1 :(得分:0)

您问题的答案是,StandardController与传递给visualforce页面的参数无关。理解了这一点后,您将更好地了解如何在测试中处理StandardController对象和查询参数。

当访问页面时抛出浏览器,通过从url检索id参数来构建StandardController。以下可能是构建页面的StandardController和Controller Extentions的步骤。

  1. 从参数列表public WebTarget webTarget(String path, Map<String, String> queryMap) { WebTarget webTarget = client.target(this.address.getUrl()).path(path); if (queryMap != null) for (Map.Entry<String, String> entry: queryMap.entrySet()) webTarget = webTarget.queryParam(entry.getKey(), entry.getValue()); return webTarget; }
  2. 中返回Id参数
  3. 使用给定的ID id=ApexPages.currentPage().getParameters().get('id');
  4. 加载Sobject
  5. 通过调用My_Object my_Object=[SELECT Id, Name FROM My_Object WHERE Id = :id]
  6. 构建具有给定对象的标准Controller
  7. 最后,使用标准控制器ApexPages.StandardController sc = new ApexPages.StandardController(my_Object)实现所有控制器扩展。
  8. 由此可以看出,通过传递sObject来实现StandardController对象,并不会自动创建一个查询参数,其参数传递的sObject的id。因此,如果出于测试目的,您需要访问查询参数,则必须将其显式添加到参数列表中MyExtension myExt = new MyExtension(sc)

答案 2 :(得分:-1)

我用它来识别请求是否来自API源

String.valueOf(URL.getCurrentRequestUrl()).toLowerCase().contains('services/soap')