Spring 启动测试中发生 HTTP 401 未经授权的错误
HTTP 401 Unauthorized error occurs in Spring Boot test
实体class
@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);
}
}
我做了一个示例 Spring 更新数据库的引导测试代码,但是如果我执行代码,测试会失败并显示以下错误消息。我已经将 spring.security.user.name
和 spring.security.user.password
定义到 application.properties 文件。
问题是什么?从 build.gradle 中删除 testImplementation 'org.springframework.security:spring-security-test'
后,我尝试重新加载,但没有任何改变。
Expecting:
<401 UNAUTHORIZED>
to be equal to:
<200 OK>
but was not.
有多种方法可以使用 @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);
实体class
@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);
}
}
我做了一个示例 Spring 更新数据库的引导测试代码,但是如果我执行代码,测试会失败并显示以下错误消息。我已经将 spring.security.user.name
和 spring.security.user.password
定义到 application.properties 文件。
问题是什么?从 build.gradle 中删除 testImplementation 'org.springframework.security:spring-security-test'
后,我尝试重新加载,但没有任何改变。
Expecting:
<401 UNAUTHORIZED>
to be equal to:
<200 OK>
but was not.
有多种方法可以使用 @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);