4

I'm trying to unit-test a simple Spring Webflow. So far I can verify transitions between the states and check variables in the request, flash, view and flow scopes.

Somehow I cannot verify that an on-render action is executed. When I run the webflow in my web application, I can see the select populated with the results of that action, so the definition must be fine. When I debug through the Spring Webflow, I can see that there are no event listeners, but I cannot quite figure out why the array of the listeners is not being populated.

I'll keep digging through the code, but I wonder if anyone faced the same issue and how it was resolved.

If this is relevant, I am mocking the service with Mockito and injecting it by overriding configureFlowBuilderContext() and registering the mock service as a bean.

Olaf
  • 6,249
  • 1
  • 19
  • 37

1 Answers1

0

I ran across this problem earlier today while trying to write a test for a new feature in a terrifying legacy Spring Web Flow app. I don't pretend to have an expert understanding of Spring Web Flow, but diving into the code, <on-render> seemed to trigger off of ViewState.render(...), which is called from ViewState.resume(...) and ViewState.doEnter(...). There are some nasty nested if-else blocks there, but it looked like it all depended on the responseAllowed and responseComplete attributes of the ExternalContext.

The reason that only the first <on-render> block would be executed in tests is because the MockExternalContext from Spring defaults to a a null responseAllowed and never changes responseComplete back to false after the first response. So I've tricked the flow into executing <on-render> attributes by writing my own implementation of the ExternalContext interface.

I literally copy-pasted the existing MockExternalContext with the following two changes:

  • Set responseAllowed to default to true:

    private Boolean responseAllowed = true;

  • Overwrite the recordResponseComplete function to never set the response to complete:

    public void recordResponseComplete() { //responseComplete = true; (Yes, this is literally just commented out) }

Soooo this is a hideous hack and probably has side effects, but Spring Web Flow is a hideous framework anyway, and this solution worked for me. YMMV.

Alex Pruss
  • 533
  • 5
  • 15