Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringBoot2:测试安全端点_Java_Spring Boot_Junit_Spring Security_Junit5 - Fatal编程技术网

Java SpringBoot2:测试安全端点

Java SpringBoot2:测试安全端点,java,spring-boot,junit,spring-security,junit5,Java,Spring Boot,Junit,Spring Security,Junit5,我有一个使用spring boot 2数据、rest、security…构建的项目,因此在该项目中我有如下rest控制器: @RestController class ProductController { private final ProductService productService; private final ProductConverter productConverter; private final UserService userService; @Autowired

我有一个使用spring boot 2数据、rest、security…构建的项目,因此在该项目中我有如下rest控制器:

@RestController
class ProductController {

private final ProductService productService;
private final ProductConverter productConverter;
private final UserService userService;

@Autowired
ProductController(ProductService productService,
                  ProductConverter productConverter,
                  UserService userService) {
    this.productService = productService;
    this.productConverter = productConverter;
    this.userService = userService;
}

@GetMapping(EndpointPath.PRODUCTS)
PageableProductsDTO getProducts(Principal principal, Pageable pageable) {
    return productService.getUsersProducts(principal.getName(), pageable);
}

@PostMapping(EndpointPath.PRODUCT)
ResponseEntity<?> createNewProduct(@Valid @RequestBody ProductDetailsDto productDetailsDto, Principal principal) {
   productService.saveProduct(productConverter.createFrom(productDetailsDto), principal.getName());
   return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
@ExtendWith({SpringExtension.class, MockitoExtension.class})
@ContextConfiguration(classes = {MessageSourceConfiguration.class})
@MockitoSettings(strictness = Strictness.LENIENT)
class ProductControllerTest {

private MockMvc mockMvc;

@Autowired
private MessageSource messageSource;

@Mock
private ProductService productService;

@Mock
private ProductConverter productConverter;

@Mock
private UserService userService;

@BeforeEach
void setUp() {
    mockMvc = MockMvcBuilders.standaloneSetup(new ProductController(productService, productConverter, userService))
                                              .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
                                              .setControllerAdvice(new ControllerAdvice(messageSource)).build();
}

@Test
void shouldReturnSetOfProducts() throws Exception {
    // Given
    String authenticatedUserEmail = "email@g.com";
    when(productService.getUsersProducts(eq(authenticatedUserEmail), ArgumentMatchers.any(Pageable.class))).thenReturn(new PageableProductsDTO(new PageImpl<>(
                                                                        List.of(new ProductDetailsDto("1234", "name", 1), new ProductDetailsDto("12345", "name 2", 2)))));

    // When - Then
    mockMvc.perform(get(EndpointPath.PRODUCTS).principal(() -> authenticatedUserEmail).accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(jsonPath("$.productDtos.content", hasSize(2)))
            .andExpect(jsonPath("$.productDtos.totalPages", is(1)))
            .andExpect(jsonPath("$.productDtos.totalElements", is(2)))
            .andExpect(jsonPath("$.productDtos.content.[*].barcode", containsInAnyOrder("1234", "12345")))
            .andExpect(jsonPath("$.productDtos.content.[*].name", containsInAnyOrder("name", "name 2")))
            .andExpect(jsonPath("$.productDtos.content.[*].price", containsInAnyOrder(1, 2)));
}
}
我还介绍了ProductController的单元测试,如下所示:

@RestController
class ProductController {

private final ProductService productService;
private final ProductConverter productConverter;
private final UserService userService;

@Autowired
ProductController(ProductService productService,
                  ProductConverter productConverter,
                  UserService userService) {
    this.productService = productService;
    this.productConverter = productConverter;
    this.userService = userService;
}

@GetMapping(EndpointPath.PRODUCTS)
PageableProductsDTO getProducts(Principal principal, Pageable pageable) {
    return productService.getUsersProducts(principal.getName(), pageable);
}

@PostMapping(EndpointPath.PRODUCT)
ResponseEntity<?> createNewProduct(@Valid @RequestBody ProductDetailsDto productDetailsDto, Principal principal) {
   productService.saveProduct(productConverter.createFrom(productDetailsDto), principal.getName());
   return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
@ExtendWith({SpringExtension.class, MockitoExtension.class})
@ContextConfiguration(classes = {MessageSourceConfiguration.class})
@MockitoSettings(strictness = Strictness.LENIENT)
class ProductControllerTest {

private MockMvc mockMvc;

@Autowired
private MessageSource messageSource;

@Mock
private ProductService productService;

@Mock
private ProductConverter productConverter;

@Mock
private UserService userService;

@BeforeEach
void setUp() {
    mockMvc = MockMvcBuilders.standaloneSetup(new ProductController(productService, productConverter, userService))
                                              .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
                                              .setControllerAdvice(new ControllerAdvice(messageSource)).build();
}

@Test
void shouldReturnSetOfProducts() throws Exception {
    // Given
    String authenticatedUserEmail = "email@g.com";
    when(productService.getUsersProducts(eq(authenticatedUserEmail), ArgumentMatchers.any(Pageable.class))).thenReturn(new PageableProductsDTO(new PageImpl<>(
                                                                        List.of(new ProductDetailsDto("1234", "name", 1), new ProductDetailsDto("12345", "name 2", 2)))));

    // When - Then
    mockMvc.perform(get(EndpointPath.PRODUCTS).principal(() -> authenticatedUserEmail).accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(jsonPath("$.productDtos.content", hasSize(2)))
            .andExpect(jsonPath("$.productDtos.totalPages", is(1)))
            .andExpect(jsonPath("$.productDtos.totalElements", is(2)))
            .andExpect(jsonPath("$.productDtos.content.[*].barcode", containsInAnyOrder("1234", "12345")))
            .andExpect(jsonPath("$.productDtos.content.[*].name", containsInAnyOrder("name", "name 2")))
            .andExpect(jsonPath("$.productDtos.content.[*].price", containsInAnyOrder(1, 2)));
}
}

除了单元测试之外,我还想确保EndpointPath.PRODUCTS是安全的。有人知道如何为此编写单元测试吗?例如:当用户未经过身份验证/授权时,预期状态为401/403。

最简单的测试,即Spring引导集成测试,如下所示

@ExtendWithSpringExtension.class @春靴测试 @AutoConfigureMockMvc @DisplayNamesample引导集成测试 公共类SpringBootIntegrationTests{ @自动连线 私有MockMvc; @DisplayNamePage是安全的 void pagesecure引发异常{ mvc.perform MockMvcRequestBuilders.get/products .andExpectstatus.Is3xx重定向 .andexpectedurlhttp://localhost/login .并预测未经验证的 ; } } 如果没有身份验证,通常不会看到401/403。因为Spring Security会将您重定向到授权服务器

重定向URL应该与重定向到授权服务器的内容相匹配

所以可能是这样的

    redirectedUrl(containsString("http://authorization.server/oauth/authorize"))
如果您有一个需要令牌的端点,那么您可以在测试中执行类似的操作

    .andExpect(status().isUnauthorized())
    .andExpect(unauthenticated())

编写一个没有auth的案例,触发API并期望状态为-401/403,同时测试401/403响应