unit-testing - @ModelAttribute Controller spring-mvc 模拟

标签 unit-testing spring-mvc mocking spring-test-mvc mockmvc

我想测试一个使用 @ModelAttribute 作为其方法参数之一的 Controller 。

public String processSaveAction(@ModelAttribute("exampleEntity") ExampleEntity exampleEntity)

@ModelAttribute 方法 getExampleEntity 正在使用 @RequestParam:

@ModelAttribute("exampleEntity")
public ExampleEntity getExampleEntity(@RequestParam(value = "id", required = true) ExampleEntity exampleEntity) {

我的 Controller 正在使用 WebDataBinder 调用工厂,该工厂根据参数“id”返回一个对象。

@Controller
public class ExampleController(){

    @Autowired private IdEditorFactory idEditorFactory;

    @InitBinder
    public void initBinder(WebDataBinder binder) {

        binder.registerCustomEditor(ExampleEntity.class, idEditorFactory.createEditor(ExampleEntity.class));
    }

    @ModelAttribute("exampleEntity")
    public ExampleEntity getExampleEntity(@RequestParam(value = "id", required = true) ExampleEntity exampleEntity) {

        //Irrelevant operations
        return exampleEntity;
    }

    @RequestMapping(method = RequestMethod.POST, params = "action=save")
    public String processSaveAction(
            @RequestParam(value = "confirmed") String exampleString,
            @ModelAttribute("exampleEntity") ExampleEntity exampleEntity,
            BindingResult result, HttpServletRequest request)
            throws IOException {

        boolean success = editorProcessor.processSaveAction(exampleString,
                exampleEntity, result, request);

        return success ? getSuccessView(exampleEntity) : VIEW_NAME;
    }
}

我的测试:

@WebAppConfiguration
public class ExampleControllerTest{

    @Mock private EditorProcessor editorProcessor;
    @Mock private IdEditorFactory idEditorFactory;
    @InjectMocks private ExampleController exampleController;

    private MockMvc mockMvc;


    @Before
    public void setUp() throws Exception {

        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(exampleController).build();

        WebDataBinder webDataBinder = new WebDataBinder(ExampleEntity.class);
        webDataBinder.registerCustomEditor(ExampleEntity.class, idEditorFactory.createEditor(ExampleEntity.class));
    }

    @Test
    public void shouldProcessSaveAction() throws Exception {

        // given
        BindingResult result = mock(BindingResult.class);
        ExampleEntity exampleEntity = mock(ExampleEntity.class);
        HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);

        given(editorProcessor.processSaveAction("confirmed", exampleEntity, result, httpServletRequest)).willReturn(true);

        // when
        ResultActions perform = mockMvc.perform(post("/").sessionAttr("exampleEntity", exampleEntity)
                                                            .param("id", "123456"
                                                            .param("action","save"));

        // then
        perform.andDo(print())
                .andExpect(status().isOk());

    }
}

我想以某种方式模拟 getExampleEntity() ,以便每次使用参数“id”执行 POST 时,我都会收到一个用于测试的模拟对象(“exampleEntity”)。

我可以在测试中引入@Binding,但是随后我必须模拟许多级别的方法(例如 initBinder -> idEditoryFactory-> editor -> hibernateTemplate 等)才能获得来自某个来源(例如数据库)的实体。

最佳答案

您可以使用 .flashAttr() 方法传入所需的 @ModelAttribute 对象,如下所示:

mockMvc.perform(post("/")                                                           
    .param("id", "123456")
    .param("action","save")
    .flashAttr("exampleEntity", new ExampleEntity()));

关于unit-testing - @ModelAttribute Controller spring-mvc 模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27483064/

相关文章:

java - 我可以在 View 层中找到 spring mvc Controller 的 URL 吗?

java - log4j 用 spring 创建空文件

android - RuntimeException : Method putExtra in android. content.Intent 未被模拟

testing - 客户端-服务器集成测试 : mock or not?

unit-testing - 创建一个 cffile action=upload 将处理的模拟请求

java - 如何模拟 super 引用(在 super 类上)?

java - 无法将 Spring MVC 依赖项添加到 Maven 项目

java - 我是否以正确的方式使用模拟?

unit-testing - web开发有必要写单元测试吗?

unit-testing - 在 Go 中模拟非接口(interface)类型