2

Is there any way to get this error: "Object row was retrieved via SOQL without querying the requested field: Any_Field_Name " in a test class so that if a new field has been added to the page, I can see that the SOQL in my constructor is not correct anymore?

The code may be simple, like this:

Class:

public class MyController {

    public Account acc { get; set; }

    public MyController() {

        acc = [Select Id From Account Limit 1];
    }
}

Page:

<apex:page controller="MyController">
    <apex:form>
        <apex:outputField value="{!acc.Name}"/>
    </apex:form>
</apex:page>

Test class:

@isTest
private class MyTestClass {

    @isTest 
    private static void test1() {

        Account testAcc = new Account(Name = 'Test');
        insert testAcc;

        Pagereference pref = Page.MyPage;

        System.Test.setCurrentPage(pref);

        MyController controller = new MyController(); ///No error at this step!
    }
}
3

Another way to approach this is the following

  • If the controller is an extension to the standard controller, the getRecord() method call will implicitly retrieve all fields mentioned on the VF page so if fields are added to the page, the controller automatically will fetch them in the getRecord() call. This is also true for getrecords() call in a standardsetController extension.
  • If the controller is a custom controller, you could use a pattern wherein you always constructed dynamic SOQL to get all fields on the sObject - so as the schema is extended, you always have every field in context (and hence, no matter what happens to the page, you have the fields for processing
  • Use try-catch loops around all your processing of sobjects - should a field be missing, you'll find it
  • Take a look at the Selector pattern as described in Apex Enterprise Patterns
0

You can directly access field values in test I guess, something like that:

   MyController controller = new MyController(); ///No error at this step!
   System.assert(controller.acc.Id != null);
   System.assert(controller.acc.Another_Fields__c != null);
  • 1
    Pavel, Well, it can work, but this solution is not dynamic at all. Imagine a system with 100+ test classes, there's no way to rewrite each of them with such assert. I'm looking for any dynamic solution where I can run all tests and be sure that there is no such error. – Dmitry Feb 27 '15 at 10:15
0

You can use PageReference.getContent() to get the actual HTML that is rendered on the page. The code below should highlight that Name is not queried in the controller.

// PageReference pr = new PageReference('/apex/MyPage?id=' + accountId);
PageReference pr = Page.MyPage;
String pageHtml = pr.getContent().toString();

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.