【问题标题】:HTTP 401 Unauthorized error occurs in Spring Boot testSpring Boot 测试中出现 HTTP 401 Unauthorized 错误
【发布时间】:2020-10-25 05:36:37
【问题描述】:

实体类

@Getter
@NoArgsConstructor
@Entity
public class Posts {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(length = 500, nullable = false)
    private String title;
    
    @Column(columnDefinition = "TEXT", nullable = false)
    private String content;
    
    private String author;
    
    @Builder
    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }
}

测试代码

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsAPIControllerTest {
    @LocalServerPort
    private int port;
    
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Autowired
    private PostsRepository postsRepository; // PostsRepository extends JpaRepository<Posts, Long>
    
    @After
    public void tearDown() throws Exception {
        postsRepository.deleteAll();
    }
    
    @Test
    public void posts_save() throws Exception {
        String title = "title";
        String content = "content";
        
        PostsSaveRequestDTO requestDTO = PostsSaveRequestDTO.builder()
                                                            .title(title)
                                                            .content(content)
                                                            .author("author")
                                                            .build();
        
        String url = "http://localhost:" + port + "/api/v1/posts";
        ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDTO, Long.class);
        
        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);
        
        List<Posts> all = postsRepository.findAll();
        
        assertThat(all.get(0).getTitle()).isEqualTo(title);
        assertThat(all.get(0).getContent()).isEqualTo(content);
    }
}

控制器

@RequiredArgsConstructor
@RestController
public class PostsAPIController {
    private final PostsService postsService;
    
    @PostMapping("/api/v1/posts")
    public Long save(@RequestBody PostsSaveRequestDTO requestDTO) {
        return postsService.save(requestDTO);
    }
    
    @PutMapping("/api/v1/posts/{id}")
    public Long update(@PathVariable Long id, @RequestBody PostsUpdateRequestDTO requestDTO) {
        return postsService.update(id, requestDTO);
    }
    
    @GetMapping("/api/v1/posts/{id}")
    public PostsResponseDTO findById(@PathVariable Long id) {
        return postsService.findById(id);
    }
}

我制作了一个更新 DB 的示例 Spring Boot 测试代码,但如果我执行代码,测试将失败并显示以下错误消息。我已经在 application.properties 文件中定义了 spring.security.user.namespring.security.user.password

有什么问题?从 build.gradle 中删除 testImplementation 'org.springframework.security:spring-security-test' 后,我尝试重新加载,但没有任何改变。

Expecting:
 <401 UNAUTHORIZED>
to be equal to:
 <200 OK>
but was not.

【问题讨论】:

  • 你能告诉你安全配置和你的控制器吗?如果这与身份验证无关,也可能与 CSRF 有关(请参阅this question)。
  • @m-alorda 我添加了控制器代码。 “安全设置”到底是什么意思?我只是在 application.properties 中设置了spring.security.user.namespring.security.user.password
  • 您需要向标头添加凭据 - 请参阅baeldung.com/spring-boot-testresttemplate

标签: java spring spring-boot spring-security spring-test


【解决方案1】:

有多种方法可以使用@WithMockUser, @WithAnonymousUser, @WithUserDetails, @WithSecurityContext 模拟安全性。您可以将这些注释与@Test 方法一起使用 您可以在项目中根据需要更改角色。您可能想探索更多细节here

@Test
@WithMockUser(username="admin",roles="ADMIN")
public void posts_save() throws Exception {
    String title = "title";
    String content = "content";
    
    PostsSaveRequestDTO requestDTO = PostsSaveRequestDTO.builder()
                                                        .title(title)
                                                        .content(content)
                                                        .author("author")
                                                        .build();
    
    String url = "http://localhost:" + port + "/api/v1/posts";
    ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDTO, Long.class);
    
    assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
    assertThat(responseEntity.getBody()).isGreaterThan(0L);
    
    List<Posts> all = postsRepository.findAll();
    
    assertThat(all.get(0).getTitle()).isEqualTo(title);
    assertThat(all.get(0).getContent()).isEqualTo(content);

【讨论】:

    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2023-04-01
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2021-08-21
    相关资源
    最近更新 更多