我正在使用Spring Boot 1.5.1构建非常基本的Web应用程序,并希望创建用于检查REST端点的集成测试.正如文档所推荐的那样,可能会使用MockMvc.
这是非常简单的测试类:
package foo.bar.first;
import ...
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ApplicationTest1 {
@Autowired
private WebApplicationContext context;
@Autowired
private MockMvc mvc;
@Test
public void shouldStartWebApplicationContext() {
assertThat(context).isNotNull();
}
@Test
public void shouldReplyToPing() throws Exception {
mvc.perform(get("/ping"))
.andExpect(status().isOk());
}
}
Run Code Online (Sandbox Code Playgroud)
正如所料,它启动完整的应用程序上下文并运行测试.
后来我创建了其他类似的测试类,并注意到每个测试类都启动了全新的应用程序上下文.实验表明,上下文仅在来自同一包的测试类之间共享.
例如,如果多次复制相同的测试类,则上下文如下:
foo.bar
first
ApplicationTest1 (shared context)
ApplicationTest2 (shared context)
second
ApplicationTest3 (brand new context)
Run Code Online (Sandbox Code Playgroud)
进一步的调查表明它与@AutoConfigureMockMvc注释有关.如果删除了注释和MockMvc相关的测试用例,则所有三个类都成功共享相同的上下文.
那么问题是如何使用MockMvc获取所有测试的共享上下文?
注意:其他资源建议MockMvcBuilders.webAppContextSetup(context).build()用于获取MockMvc实例,但它对我不起作用(处理Web请求时不涉及过滤器).
在将单元测试事后写入另一个项目创建的代码时,我遇到了如何模拟绑定到控制器的验证器的问题initBinder?
通常我会考虑确保我的输入是有效的,并在验证器中进行一些额外的调用,但在这种情况下,验证器类与通过一些数据源进行检查相结合,这一切都变得非常混乱.耦合可以追溯到一些使用的旧公共库,并且超出了我当前工作的范围来修复所有这些库.
起初我试图使用PowerMock模拟验证器的外部依赖关系并模拟静态方法,但最终遇到一个类,在创建类时需要数据源并且没有找到解决方法.
然后我尝试使用普通的mockito工具模拟验证器,但这也不起作用.然后尝试在mockMvc调用中设置验证器,但这不会注册@Mock验证器的注释.最后遇到了这个问题.但由于validator控制器本身没有字段,因此也失败了.那么,我该如何解决这个问题呢?
验证器:
public class TerminationValidator implements Validator {
// JSR-303 Bean Validator utility which converts ConstraintViolations to Spring's BindingResult
private CustomValidatorBean validator = new CustomValidatorBean();
private Class<? extends Default> level;
public TerminationValidator(Class<? extends Default> level) {
this.level = level;
validator.afterPropertiesSet();
}
public boolean supports(Class<?> clazz) {
return Termination.class.equals(clazz);
}
@Override
public void validate(Object model, Errors errors) {
BindingResult result = (BindingResult) errors;
// Check domain object against …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Spring测试来测试我的Spring MVC webapp.它使用springmvc-router进行路由,这似乎打破了测试,当我使用@RequestMapping而不是我的routes.conf文件时,它可以正常工作.
我有一个.jsp名为的文件valid.jsp,当我从Jetty运行开发站点时,它显示正常.控制器是:
@Controller
@EnableWebMvc
public class AuthController {
public String valid() {
return "valid";
}
}
Run Code Online (Sandbox Code Playgroud)
我的routes.conf文件映射GET /valid authController.valid.
现在,我的测试仪看起来像
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/test-context.xml",
"/spring/spring-security.xml",
"file:src/main/webapp/WEB-INF/mvc-config.xml"})
@WebAppConfiguration
@Import(RouteConfig.class)
public class AuthControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private AuthenticationManager authenticationManager;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc =
MockMvcBuilders.webAppContextSetup(webApplicationContext).dispatchOptions(true).build();
}
@Test
public void testValid() throws Exception {
mockMvc.perform(get("/validation-success"))
.andDo(print())
.andExpect(status().isOk());
} …Run Code Online (Sandbox Code Playgroud) 我在尝试使MockMvc在响应正文中包含异常消息时遇到了麻烦.我有一个控制器如下:
@RequestMapping("/user/new")
public AbstractResponse create(@Valid NewUserParameters params, BindingResult bindingResult) {
if (bindingResult.hasErrors()) throw BadRequestException.of(bindingResult);
// ...
}
Run Code Online (Sandbox Code Playgroud)
这里BadRequestException看上去某事像这样:
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "bad request")
public class BadRequestException extends IllegalArgumentException {
public BadRequestException(String cause) { super(cause); }
public static BadRequestException of(BindingResult bindingResult) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
我对/user/new控制器运行以下测试:
@Test
public void testUserNew() throws Exception {
getMockMvc().perform(post("/user/new")
.param("username", username)
.param("password", password))
.andDo(print())
.andExpect(status().isOk());
}
Run Code Online (Sandbox Code Playgroud)
它打印以下输出:
Resolved Exception:
Type = controller.exception.BadRequestException
ModelAndView:
View name = null
View …Run Code Online (Sandbox Code Playgroud) 我试图使用Spring MVC测试API测试以下控制器方法:
@RequestMapping(value = "/preference/email", method = RequestMethod.GET, produces = "text/html")
public String emailForm(@ModelAttribute EmailInfo emailInfo, Model model, @CurrentMember Member member) {
emailInfo.setEmail(member.getEmail());
emailInfo.setActivated(member.isActivated());
emailInfo.setToken(member.getToken());
model.addAttribute("emailInfo", emailInfo);
return "preference";
}
Run Code Online (Sandbox Code Playgroud)
当我调试以下测试方法时......
@Test
public void shouldPopulateEmailInfo() throws Exception {
when(currentMemberHandlerMethodArgumentResolver.supportsParameter(any(MethodParameter.class))).thenReturn(Boolean.TRUE);
when(currentMemberHandlerMethodArgumentResolver.resolveArgument(any(MethodParameter.class), any(ModelAndViewContainer.class), any(NativeWebRequest.class), any(WebDataBinderFactory.class))).thenReturn(currentMember);
mockMvc.perform(get("/preference/email"))//
.andDo(print())//
.andExpect(model().attribute("emailInfo.email", "currentMember@example.com"));//
}
Run Code Online (Sandbox Code Playgroud)
...我确实在emailInfo的电子邮件字段中设置了" currentMember@example.com " .
但是,我系统地得到:
java.lang.AssertionError: Model attribute 'emailInfo.email' expected:<currentMember@example.com> but was:<null>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.ModelResultMatchers$2.match(ModelResultMatchers.java:68)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
at com.bignibou.tests.controller.preference.PreferenceControllerEmailManagementTest.shouldPopulateEmailInfo(PreferenceControllerEmailManagementTest.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native …Run Code Online (Sandbox Code Playgroud) 我正在尝试运行测试Spring MVC控制器.测试编译并运行,但我的问题是我收到了一个PageNotFound警告:
WARN PageNotFound - No mapping found for HTTP request with URI [/] in DispatcherServlet with name ''
Run Code Online (Sandbox Code Playgroud)
我的测试非常简单如下:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({
"classpath*:/WEB-INF/applicationContext.xml",
"classpath*:/WEB-INF/serviceContext.xml"
})
public class FrontPageControllerTest {
@Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void init() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.ctx).build();
}
@Test
public …Run Code Online (Sandbox Code Playgroud) 我无法使用spring mvc test测试页面内容,因为它是空的.
给出最简单的控制器:
@RequestMapping(value = "/home")
public String home(HttpSession session, ModelMap model) {
return "home";
}
Run Code Online (Sandbox Code Playgroud)
相关的瓷砖配置:
<definition name="base.definition" template="/jsp/view/application.jsp">
<put-attribute name="header" value="/jsp/view/header.jsp" />
<put-attribute name="menu" value="/jsp/view/menu.jsp" />
<put-attribute name="title" value="" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/jsp/view/footer.jsp" />
</definition>
<definition name="home" extends="base.definition">
<put-attribute name="title" value="Welcome" />
<put-attribute name="body" value="/jsp/view/home/list-home.jsp" />
</definition>
Run Code Online (Sandbox Code Playgroud)
简单 list-home.jsp
<p>Welcome</p>
Run Code Online (Sandbox Code Playgroud)
而且测试:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration()
@ContextConfiguration(classes = WebTestConfig.class)
public class HomeControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void _setup() {
this.mockMvc …Run Code Online (Sandbox Code Playgroud) 我正在尝试测试(通过 Spring 测试(mvc))一个使用的控制器servletRequest.getParts()
到目前为止我所读到的就是MockMvcRequestBuilders.fileUpload().file()解决方案。但是我无法让它发挥作用。我编写了以下失败的测试
MockMultipartHttpServletRequestBuilder builder = MockMvcRequestBuilders.fileUpload("/foo")
.file(new MockMultipartFile("file", new byte[] { 1, 2, 3, 4 }));
MockHttpServletRequest rq = builder.buildRequest(null);
Assert.assertEquals(1, rq.getParts().size()); // result 0
Run Code Online (Sandbox Code Playgroud)
我浏览了 spring 代码,并且调用file(...)添加了一个元素,List<MockMultipartFile>当getParts()从另一个列表获取其元素时(Map<String, Part> parts)
必须有另一种方法来做到这一点......
编辑1
我用来测试控制器的代码是:
ResultActions result = mockMvc.perform(
MockMvcRequestBuilders.fileUpload(new URI("/url")).file("param", "expected".getBytes()))
Run Code Online (Sandbox Code Playgroud) 我想使用MockMvc在Spring Boot Application中测试登录过程.成功登录后,用户将被重定向到/ home.为了测试这个,我使用:
@Test
public void testLogin() throws Exception {
RequestBuilder requestBuilder = formLogin().user("test@tester.de").password("test");
mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().isFound());
}
Run Code Online (Sandbox Code Playgroud)
该测试提供了预期的结果.
另外,我必须测试重定向页面(/ home)的HTTP状态代码.让我们说/ home-page返回HTTP 500内部服务器错误,我需要能够测试它.
我尝试了以下方法:
@Test
public void testLogin() throws Exception {
RequestBuilder requestBuilder = formLogin().user("test@tester.de").password("test");
mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().isFound());
mockMvc.perform(get("/home").with(csrf())).andExpect(status().isOk());
}
Run Code Online (Sandbox Code Playgroud)
相反,如果获得200或500(如果出现错误),我会得到状态代码302.
在遵循重定向URL时,有没有办法正确测试HTTP状态代码?
谢谢和最好的问候
我正在尝试在spring-boot 2.x项目中使用Junit 5来测试Controller.
以下工作正常
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@WebMvcTest(TypesController.class)
@RunWith(SpringRunner.class)
public class TypesControllerTest {
@Autowired
WebApplicationContext wac;
@Test
public void testTypes() throws Exception {
webAppContextSetup(wac).build().perform(get("/types").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andExpect(content().contentType("application/json;charset=UTF-8"));
}
@EnableWebMvc
@Configuration
@ComponentScan(basePackageClasses = { TypesController.class })
static class Config {
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将其更改为使用SpringExtention,
..
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.junit.jupiter.api.extension.ExtendWith;
..
@ExtendWith(SpringExtension.class)
@WebMvcTest(TypesController.class)
public class TypesControllerTest …Run Code Online (Sandbox Code Playgroud) spring-mvc-test ×10
spring-mvc ×7
spring ×6
java ×5
spring-boot ×3
junit ×2
mockito ×2
unit-testing ×2
hamcrest ×1
junit5 ×1
mocking ×1
mockmvc ×1
spring-junit ×1
spring-test ×1