标签: spring-mvc-test

Spring Boot集成测试:@AutoConfigureMockMvc和上下文缓存

我正在使用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请求时不涉及过滤器).

junit spring-mvc spring-mvc-test spring-boot

12
推荐指数
1
解决办法
5316
查看次数

在单元测试Controller时模拟一个Spring Validator

在将单元测试事后写入另一个项目创建的代码时,我遇到了如何模拟绑定到控制器的验证器的问题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)

java unit-testing spring-mvc mockito spring-mvc-test

10
推荐指数
1
解决办法
1万
查看次数

使用MockMVC测试Spring MVC路由器

我正在尝试使用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)

java junit spring-mvc spring-mvc-test

9
推荐指数
1
解决办法
2万
查看次数

Spring MVC测试中的空异常体

我在尝试使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 exception-handling spring-mvc spring-mvc-test

9
推荐指数
1
解决办法
2825
查看次数

关于Spring MVC测试API的模型().attribute()方法的询问

我试图使用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 spring-mvc hamcrest mockito spring-mvc-test

8
推荐指数
2
解决办法
1万
查看次数

使用MockMvc进行Spring MVC测试

我正在尝试运行测试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)

java spring unit-testing mocking spring-mvc-test

7
推荐指数
2
解决办法
2万
查看次数

春季mvc测试中的空内容

我无法使用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 spring-mvc-test

7
推荐指数
1
解决办法
2207
查看次数

在 spring test mvc 中设置请求部分

我正在尝试测试(通过 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)

java spring spring-mvc spring-test spring-mvc-test

7
推荐指数
1
解决办法
3332
查看次数

使用MockMvc测试重定向URL的HTTP状态代码

我想使用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状态代码?

谢谢和最好的问候

java spring-mvc spring-mvc-test spring-boot mockmvc

7
推荐指数
1
解决办法
1万
查看次数

@ExtendWith(SpringExtension.class)无效

我正在尝试在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 spring-mvc-test spring-junit spring-boot junit5

7
推荐指数
1
解决办法
5712
查看次数