4

I have a Parent__c and Child__c object with Child records using a custom Controller Extension and Visualforce page for EDIT and NEW.

Testing this controller extension for existing Child__c records is straight forward..

@isTest
private static void saveChangesToExistingChildRecord() {

    // Setup
    Parent__c parent = insertParent();
    Child__c existingChild = insertChild(parent);

    // Execute
    ApexPages.StandardController stdCtrl = new ApexPages.StandardController(existingChild);
    Child_CtrlExt ctrlExt = new Child_CtrlExt(stdCtrl);

    PageReference customEditPage = Page.childEdit;
    customEditPage.getParameters().put('id', existingChild.Id);
    ctrlExt.save();

    // Verify
    ...
}

... but how can I do this for new records (meaning the page called for New)?

@isTest
private static void newChildIsSaved() {

    // Setup
    Parent__c parent = insertParent();
    Child__c existingChild = null;

    // Execute
    // ???
    ApexPages.StandardController stdCtrl = new ApexPages.StandardController(existingChild);
    Child_CtrlExt ctrlExt = new Child_CtrlExt(stdCtrl);

    PageReference customEditPage = Page.childEdit;
    // ???
    customEditPage.getParameters().put('id', existingChild.Id); 
    ctrlExt.save();

    // Verify
    ...
}

Passing around null values to mimic a not yet existing object does not seem to work. When I look at the page params I see a cryptic LKID param, which seems to pass information about the parent object.

2

StandardController has a constructor taking an SObject, but it's not required that the passed object exists in the database. Thanks to this you can simply say:

new ApexPages.StandardController(new Child__c(parent__c = parent.Id));

Controller extensions should call standardController.getRecord() or standardController.getId() to access record's ID, and understand that it will be blank if a record is just created.

| improve this answer | |
  • But I don't want my test to create and pass an in-memory Child__c record at all. The creation should be transparently handled inside the ctrl ext under test. – Robert Sösemann Jan 2 '14 at 12:43
  • 1
    Now I'm really confused - have I misunderstood your question? When you open a page using a Standard Controller, Salesforce implicitly creates an in-memory object. Why would you like the extension instead of the standard controller to instantiate the object? How would you like to test your code if not simulating the real behavior of Visualforce? – endrju Jan 2 '14 at 13:05
1

Let's imagine you have an existing Parent_c on a detail page and in the related list Child_c of Parent__c, there is a New button.

When the New button is clicked, the controller extension for Child_c is invoked. The controller will be passed an object of Child_c with parent__c populated to point at the instance of the parent object.

Thus, the test class is as follows:

@isTest
private static void newChildIsSaved() {

// Setup
Parent__c parent = insertParent();
Child__c existingChild = new Child__c(parent__c = parent.id)

// Execute
Test.setCurrentPageReference(Page.childEdit);
ApexPages.StandardController stdCtrl = new ApexPages.StandardController(existingChild);
Child_CtrlExt ctrlExt = new Child_CtrlExt(stdCtrl);

ctrlExt.save();

// Verify
...

}

| improve this answer | |

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.