1

I read through other Constructor posts but it seems that maybe my criteria is little bit unique in terms of my approach, I am writing a test class for a working page/apex class that works perfect without any issue but the issue comes when I'm trying to write a test class.

VF page:

<apex:page controller="EmployeeController" action="{!ActivateMe}">  
</apex:page>

EmployeeController:

public Id empId {get;set;}
public class EmployeeController{

     empId = Apexpages.currentPage().getParameters().get('id');
     //more code
}

public PageReference ActivateMe() 
{
    //more code here....
}

The above code is working fine

Now the issue I'm having is when I test code as follows:

Test Code:

static testMethod void testMethod1() 
{
    Employee__c newEmp = new Employee__c();
    newEmp.Name = 'test';
    insert newEmp;

    PageReference pageRef = Page.EmployeePage; // Add your VF page Name here
    pageRef.getParameters().put('id', newEmp.Id);
    Test.setCurrentPage(pageRef); 

    ApexPages.StandardController sc = new ApexPages.StandardController(newEmp);
    EmployeeController testEmp = new EmployeeController(sc);

    testEmp.ActivateMe();

}

Constructor not defined: [EmployeeController].(ApexPages.StandardController)

Okay, so after reading about the error and I found that you must use the following constructor:

so the new version of my constructor for the EmployeeController class would be:

public EmployeeController(ApexPages.StandardController controller) 
{
   //...
}

My test method ran successfully but the VF page breaks due to adding the standard constructor.

my question is what is the best approach to the above scenario to work both VFP and test class?

2

If you're certain that your markup as specified is the way you want to go (no standardController attribute), then just use the empty constructor in your test:

ApexPages.currentPage().getParameters().put('id', '<some_value>');
EmployeeController controller = new EmployeeController();

As a side note, you don't really have to set the current page reference. The controller code is going to use the same one as the test, and I've never seen a use case that required me to actually have my controller verify anything about the current page reference besides the parameters or headers, which you can set from the text context.

  • 1+ Thanks, I don't know why I did not think of that. – Nick Kahn Mar 30 '17 at 1:08
1

Your page is not written "correctly." I say this because it's clearly meant to be a record page, but you're not using a standard controller. I'd advise that you change your code as follows:

<apex:page standardController="Employee__c" extensions="EmployeeController" action="{!ActivateMe}"></apex:page>

public class EmployeeController {
    Employee__c employeeRecord;
    public EmployeeController(ApexPages.StandardController controller) {
        employeeRecord = (Employee__c)controller.getRecord();
        // more code here
    }
    public void ActivateMe() {
        // more code here
    }
}
  • Then the Apex Class would become an extension. I do agree that it's more natural to write an extension than a custom controller in this instance, though we don't know a ton about the use case. – Adrian Larson Mar 30 '17 at 1:07
1

If you are using the standardController attribute on your Visualforce page, you should create the controller instance using an ApexPages.StandardController as parameter. Otherwise (your case), you don't need this and can instantiate the class without the StandardController.

It is worth noticing that if you want the page to be accessible through a button on a related list, the page must also implement the recordSetVar attribute and use the ApexPages.StandardSetController on the back-end.

Your test would be as simple as:

Test.startTest();
MyClassInstance c = new MyClassInstance();
c.myMethod();
Test.stopTest();

Of course, you still need to instantiate your test data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.