Test Model Binding in Wicket Form

2024-12-18




When working with Apache Wicket, ensuring that your forms are correctly bound to the right model is critical. In this post, we'll demonstrate how to detect and handle a case where the wrong object is bound to the form model.

Wicket Form

A Form in Wicket is a component that collects user input. It is responsible for rendering the form fields, handling user submissions, and managing validation. Forms can contain various input components such as text fields, checkboxes, and dropdowns. When a user submits a form, Wicket processes the input, validates it.

Here's a Wicket form designed to edit a cat's name. The form uses a CompoundPropertyModel bound to a CatEditing object.

add(new Form<Void>("form") {
                    
    private CatEditing catEditing = catEditing.forEdit(cat);

    @Override
    protected void onInitialize() {
        super.onInitialize();

        setDefaultModel(new CompoundPropertyModel<CatEditing>(catEditing));
        
        add(new RequiredTextField<String>("catName").setLabel(Model.of("Cat Name")));
    }

    @Override
    protected void onSubmit() {
        accountService.txUpdateCatName(catEditing, getSignInCat());
        info("update successfully");
    }
});

 

Test for form submit

@Test
public void testSubmit() throws Exception {
    startPage();

    mockAccountService.txUpdateCatName(EasyMock.anyObject(UserEditing.class), EasyMock.eq(operator));
    
	// 若setDefaultModel設成cat而非catEditing,可透過Argument的值檢查出來
    EasyMock.expectLastCall().andAnswer(() -> {
        Object[] args = EasyMock.getCurrentArguments();
        CatEditing actualEditing = (catEditing) args[0];
        Cat actualOperator = (cat) args[1];
        assertEquals("testCat", actualEditing.getCatName());
        assertEquals("Sys", actualOperator.getRolesString());
        return null;
    });

    EnhancedFormTester formTester = tester.newFormTester("form");
    control.replay();

    formTester.setValue("catName", "testCat");
    formTester.submit();

    control.verify();

    tester.assertInfoMessages("update successfully");
}

If we mistakenly set the default model to a Cat object instead of a CatEditing object:

setDefaultModel(new CompoundPropertyModel<Cat>(cat));

Expected Failure

The test will throw an error due to the mismatch:

Caused by: org.junit.ComparisonFailure: expected:<[testCat]> but was:<[catName]>

This occurs because the RequiredTextField is bound to a catName property that exists in the Cat object but not in the CatEditing object.

Conclusion

Testing Wicket forms for correct model binding is essential to avoid subtle bugs. By mocking dependencies and validating interactions, we can ensure the form behave as expected. 

Reference







Login to like - 0 Likes



Comments...


No Comments Yet...



Add Comment...




Footer with Icons