我一直在为一个简单的spring Web应用程序编写一些简单的单元测试例程.当我在资源的getter方法上添加@JsonIgnore注释时,生成的json对象不包含相应的json元素.因此,当我的单元测试例程尝试测试它是否为null(这是我的情况的预期行为,我不希望密码在json对象中可用)时,测试例程会遇到异常:
java.lang.AssertionError:JSON路径没有值:$ .password,exception:路径没有结果:$ ['password']
这是我编写的单元测试方法,用is(nullValue())方法测试'password'字段:
@Test
public void getUserThatExists() throws Exception {
    User user = new User();
    user.setId(1L);
    user.setUsername("zobayer");
    user.setPassword("123456");
    when(userService.getUserById(1L)).thenReturn(user);
    mockMvc.perform(get("/users/1"))
            .andExpect(jsonPath("$.username", is(user.getUsername())))
            .andExpect(jsonPath("$.password", is(nullValue())))
            .andExpect(jsonPath("$.links[*].href", hasItem(endsWith("/users/1"))))
            .andExpect(status().isOk())
            .andDo(print());
}
我也尝试过使用jsonPath().exists()获得类似的异常,说明路径不存在.我正在分享更多的代码片段,以便整个情况变得更具可读性.
我正在测试的控制器方法看起来像这样:
@RequestMapping(value="/users/{userId}", method= RequestMethod.GET)
public ResponseEntity<UserResource> getUser(@PathVariable Long userId) {
    logger.info("Request arrived for getUser() with params {}", userId);
    User user = userService.getUserById(userId);
    if(user != null) {
        UserResource userResource = new UserResourceAsm().toResource(user);
        return new ResponseEntity<>(userResource, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}
我使用spring hateos资源汇编程序将实体转换为资源对象,这是我的资源类:
public class …我的带@ControllerAdvice注释的控制器看起来像这样:
@ControllerAdvice
public class GlobalControllerExceptionHandler {
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AuthenticationException.class)
    public void authenticationExceptionHandler() {
    }
}
当然我的开发是测试驱动的,我想在JUnit测试中使用我的异常处理程序.我的测试用例如下所示:
public class ClientQueriesControllerTest {
    private MockMvc mockMvc;
    @InjectMocks
    private ClientQueriesController controller;
    @Mock
    private AuthenticationService authenticationService;
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }
    @Test
    public void findAllAccountRelatedClientsUnauthorized() throws Exception {
        when(authenticationService.validateAuthorization(anyString())).thenThrow(AuthenticationException.class);
        mockMvc.perform(get("/rest/clients").header("Authorization", UUID.randomUUID().toString()))
                .andExpect(status().isUnauthorized());
    }
}
可能我需要注册ControllerAdvice课程.怎么做?
有没有人有任何提示,或者有人知道如何测试HTTP响应对象返回的"错误消息"吗?
@Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
响应:
MockHttpServletResponse:
              Status = 200
       Error message = null
             Headers = {Content-Type=[application/json;charset=UTF-8]}
        Content type = application/json;charset=UTF-8
我很难弄清楚如何在spring mvc中的JSON文档响应中使用jsonPath断言.也许有比使用jsonPath更好的方法来完成这个特定的场景.我想验证链接数组是否具有"self"的rel项,而"self"对象的"href"属性也具有等于"/"的"href"属性.JSON响应如下所示:
 {  
   "links":[  
      {  
         "rel":[  
            "self"
         ],
         "href":"/"
      },
      {  
         "rel":[  
            "next"
         ],
         "href":"/1"
      }
   ]
}
我试过这个,我可以看到它有rel [0]有自己,但我宁愿不依赖于链接数组中的位置和自我的rel数组,并实际测试链接中的href是什么[rel] [self]是"/".有任何想法吗?
 @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(welcomeController).build();
  }
  @Test
  public void givenRootUrl_thenReturnLinkToSelf() throws Exception {
    mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
        .andExpect(jsonPath("$.links[0].rel[0].", is("self")));
  }
在使用Spring MockMVC的JUnit测试中,有两种方法可以作为Spring Security用户进行身份验证:@WithMockUser使用提供的凭据创建虚拟用户,@WithUserDetails获取用户的名称并UserDetails使用自定义UserDetailsService(the UserDetailsServiceImpl)将其解析为正确的自定义实现.
在我的例子中,UserDetailsService从数据库加载用户.我想要使用的用户插入@Before了测试套件的方法中.
但是,我UserDetailsServiceImpl找不到用户.
在我@Before,我插入这样的用户:
User u = new User();
u.setEMail("test@test.de");
u = userRepository.save(u);
并在UserDetailsServiceImpl:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = this.userRepository.findOneByEMail(username);
    if (user == null)
        throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
    return user;
}
如何使用创建的帐户@Before有@WithUserDetails?
我正在尝试在我的REST API中对登录和安全性进行单元测试,因此我尝试尽可能接近地模拟现实生活中的请求序列.
我的第一个请求是:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).
    addFilters(springSecurityFilterChain).build();
this.mapper = new ObjectMapper();
....
MvcResult result=mockMvc.perform(get("/login/csrf")).andExpect(status().is(200)).andReturn();
Cookie[] cookies = result.getResponse().getCookies();
(参见关于pastebin的完整课程).
我尝试在这里获取cookie以便稍后能够使用收到的CSRF令牌登录,但是cookies数组是空的!
但是,如果我运行我的应用程序并打电话
curl -i http://localhost:8080/login/csrf
我确实得到了一个Set-Cookie标头,可以稍后使用该cookie(以及CSRF令牌)进行身份验证.
所以问题是:我如何让MockMvc向我返回一个cookie?
我在使用MockMvc测试Spring Boot应用程序时遇到了一些麻烦.
我有以下测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SpringConfiguration.class, SecurityConfiguration.class})
@IntegrationTest({"server.port=8080"})
@WebAppConfiguration
public class DemoTest {
@Autowired
private EmbeddedWebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testGetAccountUnauthenticated() throws Exception {
    mockMvc.perform(get("/accounts/1").accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isUnauthorized());
}
}
这导致HTTP 200而不是401.我启用了组件扫描和自动配置,并在我的SecuityConfiguration类中配置了spring安全性,如下所示:
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity // required for use of @AuthenticationPrincipal in MVC controllers.
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
    web.debug(true);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    //set …spring-security spring-test spring-test-mvc spring-boot mockmvc
我有方法的控制器PUT方法,它接收multipart/form-data:
   @RequestMapping(value = "/putIn", method = RequestMethod.PUT)
   public Foo updateFoo(HttpServletRequest request,
                           @RequestBody Foo foo,
                           @RequestParam("foo_icon") MultipartFile file) {
    ...
   }
我想用它来测试它MockMvc.不幸的是,MockMvcRequestBuilders.fileUpload基本上创建了MockMultipartHttpServletRequestBuilder一个POST方法:
super(HttpMethod.POST, urlTemplate, urlVariables)
编辑:
我一定能 ,我不能创建自己的实现MockHttpServletRequestBuilder,比如
public MockPutMultipartHttpServletRequestBuilder(String urlTemplate, Object... urlVariables) {
    super(HttpMethod.PUT, urlTemplate, urlVariables);
    super.contentType(MediaType.MULTIPART_FORM_DATA);
}
因为MockHttpServletRequestBuilder有包本地构造函数.
但我想知道是否更方便有任何方法可以做到这一点,可能是我错过了一些现有的课程或方法吗?
我正在使用MockRestServiceServer在我的REST控制器上编写某种集成测试来模拟后端行为.我现在想要实现的是模拟来自后端的非常慢的响应,这最终会导致我的应用程序超时.它似乎可以用WireMock实现,但目前我想坚持使用MockRestServiceServer.
我正在创建这样的服务器:
myMock = MockRestServiceServer.createServer(asyncRestTemplate);
然后我嘲笑我的后端行为,如:
myMock.expect(requestTo("http://myfakeurl.blabla"))
            .andExpect(method(HttpMethod.GET))
            .andRespond(withSuccess(myJsonResponse, MediaType.APPLICATION_JSON));
是否有可能在响应中添加某种延迟或超时或其他类型的延迟(或者可能是整个模拟服务器甚至是我的asyncRestTemplate)?或者我应该切换到WireMock还是Restito?
我正在尝试测试一些受保护的端点的安全配置@PreAuthorize(#oauth2.hasScope('scope').当通过Postman使用不具有所需范围的访问令牌访问此类端点时,将返回以下HTTP状态码403(禁止):
{
    "error": "insufficient_scope",
    "error_description": "Insufficient scope for this resource",
    "scope": "scope"
}
这是我想要的预期行为.
在尝试测试此配置时,Springs会NestedServletException干扰我的测试用例,然后才能完成预期的结果.
这是我要测试的控制器的简化版本:
@RestController
@RequestMapping(value = "/api")
public class OauthTestingResource {
    @PreAuthorize(#oauth2.hasScope('scope'))
    @RequestMapping(value = "/scope", method = RequestMethod.GET)
    public void endpoint() {
        // ...
    }
}
这是相应的测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyApplication.class)
@WebAppConfiguration
public class AuthorizationTest {
    @Autowired
    protected WebApplicationContext webApplicationContext;
    protected SecurityContext securityContext = Mockito.mock(SecurityContext.class);
    @Before
    public void setup() throws Exception {
        this.mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        SecurityContextHolder.setContext(securityContext);
    }
    protected Authentication createMockAuth(Client …mockmvc ×10
java ×6
spring ×6
spring-mvc ×4
junit ×3
jsonpath ×2
unit-testing ×2
cookies ×1
mocking ×1
mockito ×1
spring-boot ×1
spring-test ×1