Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Spring MVC BindingResult when using annotations

I'm migrating a Spring MVC controller to use the newer style annotations, and want to unit test a controller method that validates a command object (see simple example below).

 @RequestMapping(method = RequestMethod.POST)
public String doThing(Command command, BindingResult result,
                    HttpServletRequest request, HttpServletResponse response,
                    Map<String, Object> model){ 
    ThingValidator validator = new ThingValidator();
    validator.validate(command, result);
... other logic here
    }

My problem is I have to call the controller's method in my unit test, and provide mock values to satisfy its signature to exercise the code properly, and I cannot work out how to mock a BindingResult.

In the old style Controller the signature simply took a HttpServletRequest and HttpServletResponse, which were easily mockable, but due to the flexibility of the new annotation style, one has to pass a lot more in via the signature.

How can one mock a Spring BindingResult for use in a unit test??

like image 931
Al Power Avatar asked May 18 '09 12:05

Al Power


2 Answers

You could also use something like Mockito to create a mock of the BindingResult and pass that to your controller method, ie

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verifyZeroInteractions;

@Test
public void createDoesNotCreateAnythingWhenTheBindingResultHasErrors() {
    // Given
    SomeDomainDTO dto = new SomeDomainDTO();
    ModelAndView mv = new ModelAndView();

    BindingResult result = mock(BindingResult.class);
    when(result.hasErrors()).thenReturn(true);

    // When
    controller.create(dto, result, mv);

    // Then
    verifyZeroInteractions(lockAccessor);
}

This can give you more flexibility and simplify scaffolding.

like image 190
Ted Pennings Avatar answered Sep 28 '22 04:09

Ted Pennings


BindingResult is an interface so can you not simply pass in one of Springs implementations of that interface?

I don't use annotations in my Spring MVC code but when I want to test the validate method of a validator I just pass in an instance of BindException and then use the values it returns in assertEquals etc.

like image 20
Mark Avatar answered Sep 28 '22 03:09

Mark