Message: [Message]
When it comes to radio buttons in Wicket, there are two options, either use the simple RadioChoice or build it all with a RadioGroup and Radio elements. The latter option also needs a repeater for the Radio widgets.
<table wicket:id="radioGroup"> <tr wicket:id="radioRepeater"> <td><input type="radio" wicket:id="radio" /></td> <td><span wicket:id="radioName"></span></td> </tr> </table>
Each radio button is connected to an object, as opposed to the simpler RadioChoice. We use a table where we can put the properties of each object on a row.
Use the same model object for the Form as for the RadioGroup
RadioGroupFormObject selection = new RadioGroupFormObject(); PropertyModel<String> model = new PropertyModel<String>(selection, "radio"); selection.setRadio("no selection"); setDefaultModel(model); final RadioGroup<String> radioGroup = createRadioGroup(model);
The hard part is the testing. The AjaxFormChoiceComponentUpdatingBehavior does not lend itself to execution from the test environment. Instead we have to rely on the onSelectionChanged when testing. It is not AJAX so the page will be reloaded. Since there is a difference between the test environment and the production environment, we must merge the logic at earliest possibility. Here we have a method updateLabel that are called in both cases.
new RadioGroup<String>(RADIO_GROUP, model) { @Override protected boolean wantOnSelectionChangedNotifications() { return false; } @Override protected void onSelectionChanged(Object newSelection) { log.debug("onSelectionChanged: " + newSelection); Object modelObject = getDefaultModelObject(); updateLabel(null, modelObject); } ... new AjaxFormChoiceComponentUpdatingBehavior() { private static final long serialVersionUID = 1L; @Override protected void onUpdate(AjaxRequestTarget target) { Object modelObject = getComponent().getDefaultModelObject(); log.debug(String.format("onUpdate: %s", modelObject)); updateLabel(target, modelObject); } }; }
You could of course look up the behavior of the component and execute it. However, that seems to set everything to null so we had to give that one up.
Instead, we use the onSelectionChanged method.
private void triggerRadioGroupUpdate() { String path = RadioGroupPage.FORM + ":" + RadioGroupPage.RADIO_GROUP; RadioGroup<String> rg = (RadioGroup<String>) tester.getComponentFromLastRenderedPage(path); rg.onSelectionChanged(); }
Thus, we can write test code like this:
@Test public void whenSelectingAnOptionThenDisplayMessage() { RadioGroupPageAjaxOverride testPage = createTestPage(); fillInTheForm(CHOICE_2_INDEX); triggerRadioGroupUpdate(); String actualMessage = getTheResult(); assertOnlyTheMessageIsDisplayed(testPage, CHOICE_2_MESSAGE, actualMessage); } private FormTester fillInTheForm(int choiceIndex) { FormTester formTester = tester.newFormTester(RadioGroupPage.FORM); formTester.select(RadioGroupPage.RADIO_GROUP, choiceIndex); return formTester; }