+ Start a Discussion
Keith987Keith987 

Can Apex code that generates Dynamic Visualforce Components by unit tested?

I have some Apex code that creates a Component.Apex.PageBlockSection containing many Component.Apex.InputField objects. This works fine when invoked from an apex:dynamicComponent tag in a Visualforce page.

 

But when I run the code in this test to ensure that there are not any exceptions and to add to the code coverage total I get the "An internal server error has occurred" error page:

 

@isTest
private class DetailsDynamicComponentFactoryTest {
    @isTest
    static void test() {
    	System.assertNotEquals(null, new DetailsDynamicComponentFactory(true, true, true, true, true).create('Details', true));
    }
}

 

Has anyone succeeded in running such code from a test?

 

Thanks,

Keith

Best Answer chosen by Admin (Salesforce Developers) 
Keith987Keith987

Support came up with the workaround that if "required" is set before the expression value the error does not occur so that's what I'm going with. Hopefully whatever causes the error will also eventually be fixed.

 

So the answer to "Can Apex code that generates Dynamic Visualforce Components by unit tested?" is generally "yes".

All Answers

aballardaballard

I've certainly created components from test methods.  

Internal server error definitely indicates a (Salesforce) bug.

 

What is the error id from the internal server error message you get?

Keith987Keith987

Good to know that it should work. The error information is e.g.:

 

Error ID: 159331007-37286 (-1057626469)

 

Thanks,

Keith

aballardaballard

looks like something has gone badly wrong with the error handling.    The error message you should have got might be 

 

" Invalid value for property required: Could not resolve the entity from <apex:inputField> value binding {!benefitClaimedDetails.Cause__c}. <apex:inputField> can only be used with SObject fields"

 

Does that make sense to you?  (Is benefitClaimedDetails a valid object reference?  Is cause__c defined?    )

 

 

(Not sure if this corresponds to your occurrence of that error code, however)

 

 

 

 

Keith987Keith987

Yes that does make sense because the page that the components generated by the Apex code are used in has a controller that has a property called benefitClaimedDetails that is a reference to an SObject that has a field named Cause__c.

 

The component creating Apex code does things like this:

 

Component.Apex.InputField field = new Component.Apex.InputField();
field.expressions.value = '{!benefitClaimedDetails.Cause__c}';

so I can see the potential for problems.

 

Can you suggest a coding pattern that avoids this problem in tests (where there is no notion of a page) yet still binds the components to controller fields when they are hooked into a page?

 

Thanks,

Keith

aballardaballard

Is this dynamic code in the page controller? or a controller for some other component?   I think it should be valid IF an equivalent static reference at the point where the dynamic component is inserted would have been valid. 

 

Interesting that the error message seems to refer to property "required". 

 

If you have access to Salesforce support, perhaps you should open a case so this can be investigated properly. 

Keith987Keith987

Yes I've opened a case with Salesforce support.

 

The problem occurs only in the test code shown above; the code works fine with the page and controller. So the issue is how to test the component creating code.

 

There is Test.setCurrentPage available in tests. I've tried that but with "An internal server error has occurred" result its hard to know if anything has changed. I would be surprised if this call supplied enough context to fix the problem though.

Keith987Keith987

Support came up with the workaround that if "required" is set before the expression value the error does not occur so that's what I'm going with. Hopefully whatever causes the error will also eventually be fixed.

 

So the answer to "Can Apex code that generates Dynamic Visualforce Components by unit tested?" is generally "yes".

This was selected as the best answer