简体   繁体   English

测试Thymeleaf表单/ Spring MVC Controller交互的最佳方法

[英]Best way to test Thymeleaf form / Spring MVC Controller interaction

I am working on a Spring Boot app using Thymeleaf & Spring MVC, and I came across a bug in the code where someone had bound the Spring MVC model to 2 different HTML form fields: 我正在使用Thymeleaf和Spring MVC开发Spring Boot应用程序,我在代码中遇到了一个错误,其中有人将Spring MVC模型绑定到2个不同的HTML表单字段:

<input th:field="*{userModel.name}" type="text" />
<input id="name" th:field="*{userModel.name}" type="hidden" />

This was causing the name field in the model of the controller to get set to a string of comma-separated values. 这导致控制器模型中的name字段被设置为逗号分隔值的字符串。 "Steve,Steve" for example. “史蒂夫,史蒂夫”,例如。 I fixed the problem, but I'm wondering the simplest way to write a regression test for this. 我解决了这个问题,但我想知道为此编写回归测试的最简单方法。 There is a Spring MVC testing framework, which I could use as on this blog post , but what I really want to test is the interaction between the rendered template and the controller, not just the controller. 有一个Spring MVC测试框架,我可以在这个博客文章中使用 ,但我真正想测试的是渲染模板和控制器之间的交互,而不仅仅是控制器。

I could use a selenium test, but I recently read this Martin Fowler bliki/article (blikticle?) in which he says: 我可以使用硒测试,但我最近读了这篇Martin Fowler bliki /文章 (blikticle?),他说:

In particular a common problem is that teams conflate the concepts of end-to-end tests, UI tests, and customer facing tests. 特别是一个常见的问题是团队将端到端测试,UI测试和面向客户的测试的概念混为一谈。 These are all orthogonal characteristics. 这些都是正交特征。

I think this is a great point. 我认为这是一个很好的观点。 What I would like to write is a UI component (integration?) test, I think. 我想写的是UI组件(集成?)测试。 Something smaller than loading up the whole page. 比装载整个页面小的东西。 Something only testing the form generation and submission. 只测试表单生成和提交的东西。

Another idea I had was that this sort of bug might be best caught through a static-analysis tool, but that's a bit beyond my scope. 我的另一个想法是,这种错误可能最好通过静态分析工具捕获,但这有点超出了我的范围。

In this project, I've realized that the interactions between Spring MVC and the HTML forms are a common place for errors, so it would be nice to have a way to test just these interactions. 在这个项目中,我意识到Spring MVC和HTML表单之间的交互是错误的常见位置,所以有一种方法可以测试这些交互。

EDIT: 编辑:

Upon further consideration, I think these are the steps I want in my test: 经过进一步考虑,我认为这些是我在测试中想要的步骤:

  1. Select <form> tag out of a template's thymeleaf template and render it, passing in appropriate data on the model 从模板的百万美元模板中选择<form>标签并进行渲染,并在模型上传递适当的数据
  2. Possibly programmatically edit the rendered form values (from Java) to simulate JavaScript interactions. 可能以编程方式编辑呈现的表单值(来自Java)以模拟JavaScript交互。
  3. Generate a browser's http POST request based on rendered form. 根据呈现的表单生成浏览器的http POST请求。
  4. Use whatever Spring uses to convert POST request to the controller's model parameter 使用Spring用于将POST请求转换为控制器的模型参数
  5. Either call the controller and verify the results, or just assert that the model was created correctly 调用控制器并验证结果,或者只是断言模型是否正确创建

I think I may able to do #1 with Thymeleaf's fragment selectors or by refactoring my form out into a separate template. 我想我可以用Thymeleaf的片段选择器做#1,或者将我的表格重构成一个单独的模板。 #2 I can do easily with JSoup. #2我可以轻松地使用JSoup。 It's #3 & #4 that I'm not sure how to do. 这是#3&#4,我不知道该怎么做。 #3 I might be able to write myself maybe, depending on how the HttpServletRequest mocks work. #3我也许可以写自己,这取决于HttpServletRequest模拟的工作方式。 #4 seems like it's gotta be available in Spring somewhere but I'm new to Spring. #4似乎它必须在Spring的某个地方可用,但我是Spring的新手。

UPDATE: 更新:

Looking at the WebDataBinder as a possible solution for #4. WebDataBinder视为#4的可能解决方案。

I think you should test the functionality and to get good path-coverage of the controller calling the controller directly, mocking the underlying services. 我认为您应该测试功能并获得控制器直接调用控制器的良好路径覆盖,模拟底层服务。 Then you can test if the model is correctly filled. 然后,您可以测试模型是否正确填充。

You can test a complex template with Thymeleaf-test infrastructure. 您可以使用Thymeleaf测试基础架构测试复杂模板。

However, at the end of the day, everything must work together. 但是,在一天结束时,一切都必须协同工作。 This test should be done with selenium, to check the the variable-names match (So your regression). 这个测试应该用硒来完成,以检查变量名匹配(所以你的回归)。 Normally you should only need a few tests for each page. 通常,您只需要为每个页面进行一些测试。 If you have a lot of JS you should test complex JS functionality with buster.js. 如果你有很多JS,你应该用buster.js测试复杂的JS功能。 The htmlunitdriver of selenium is really fast, so I assume that the performance shouldn't be a big issue. 硒的htmlunitdriver非常快,所以我认为性能不应该是一个大问题。 But don't test all controller- or service-paths with selenium. 但是不要用硒测试所有控制器或服务路径。

A few years later, it looks like you can do now essentially what I wanted using HtmlUnit/SpringMVC Test integration. 几年后,看起来你现在可以使用HtmlUnit / SpringMVC Test集成基本上做我想要的。 It will shortcut any calls you make to your controller and use MockMVC instead, without a Servlet Container. 它会快速调用您对控制器的任何调用,并使用MockMVC而不使用Servlet容器。

So, you get the advantage of a html-smart client library to wrap the front end like a browser without the overhead of the servlet container and with the ability to mock out whatever you want to under the controller. 因此,您可以获得html智能客户端库的优势,可以像浏览器一样包装前端,而不需要servlet容器的开销,并且能够在控制器下模拟出您想要的内容。

https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-server-htmlunit https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-server-htmlunit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM