5

In Apex Unit tests why doesn't the MyConrtoller myCont = new MyController(StandardContoller); call set the current page?

For instance if I have this page:

<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> 

If my unit tests creates this:

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);

Why does ApexPages.currentPage().getParameters().get('id'); fail? I have to do:

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

What is the point of passing in the dbObj to StandardController if it doesn't do anything with it? Is the intent that you send in a blank object and the extenstion uses this object? There doesn't seem to be a lot of documentation for StandardControllers and Unit Testing...

Thanks!

rjbez
  • 742
  • 2
  • 11
  • 20

3 Answers3

2

One way to go about this in a test scenario would be something like this:

// 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);

Now to your question why does getParameters().get('id') fail? You can initiate a StandardController without a record id which would give you a new record and automatically insert the record if you use the default save PageReference.

Thomas Stachl
  • 408
  • 2
  • 8
  • 1
    Although this does work, it doesn't really make it ideal. I would think that if I pass in a non-null object it would use that object to render the page instead of creating a new object with it... – rjbez Aug 21 '12 at 20:10
0

The anwser to your question is that the StandardController has nothing to do with the parameters passed to the visualforce page. When you understand this, you will better understand how to deal with StandardController object and query parameters in your Tests.

When the page is accessed throw the browser, the StandardController is build by retrieving the id param from the url. The following could be the steps of building StandardController and Controller Extentions of the page.

  1. Retrive the Id param from the parameters List id=ApexPages.currentPage().getParameters().get('id');
  2. Load the Sobject with the given Id My_Object my_Object=[SELECT Id, Name FROM My_Object WHERE Id = :id]
  3. Build the standard Controller with the given object by calling ApexPages.StandardController sc = new ApexPages.StandardController(my_Object)
  4. Finally, instanciate all the controller extentions with the standard controller MyExtension myExt = new MyExtension(sc).

From this, you can notice that instaciating the StandardController object by passing an sObject does not automatically create a query parameter with the id of the sObject passed as argument. So if for your testing purpose you need to access query parameters, you have to add it explicitly to the list of parameters as you did it ApexPages.currentPage().getParameters().put('id', dbObj.Id);.

Genoud Magloire
  • 523
  • 6
  • 15
-1

I used this to identify if the request came from an API source

String.valueOf(URL.getCurrentRequestUrl()).toLowerCase().contains('services/soap')
Lodder
  • 19,583
  • 8
  • 57
  • 94