【发布时间】:2023-01-11 11:32:55
【问题描述】:
我在使用 spring boot 和 JUnit 5,Mockito 进行控制器层测试时遇到了一些错误。
@WebMvcTest(UsersController.class)
@AutoConfigureMockMvc
public class UsersControllerTest {
private MockMvc mockMvc;
@Autowired
private UsersController usersController;
@MockBean
private UsersService usersService;
@MockBean
private JwtTokenProvider jwtTokenProvider;
@MockBean
private AuthenticationManager authenticationManager;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders
.standaloneSetup(usersController)
.setControllerAdvice(UsersExceptionHandler.class)
.build();
}
@Test
@DisplayName("[Controller] Register")
void Controller_Register_Test() throws Exception {
//given
Users users = Users.builder()
.usersId("test@gmail.com")
.nickname("testNickname")
.password("testPassword")
.build();
UsersResponseDto responseDto = UsersResponseDto.builder()
.users(users)
.build();
UsersSaveRequestDto requestDto = new UsersSaveRequestDto(
"test@gmail.com",
"testNickname",
"testPassword"
);
//mocking
when(usersService.save(any())).thenReturn(responseDto);
//when
mockMvc.perform(post("/api/users/save")
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(requestDto))
)
//then
.andExpect(status().isOk())
.andExpect(content().json(new ObjectMapper().writeValueAsString(responseDto)))
.andDo(print());
}
}
我想测试 ExceptionHandler,所以我使用 @BeforeEach 注释来初始化 mockMvc。
但是,在添加 setup() 方法之后,像这样抛出 JSONException。
Unparsable JSON string:
org.json.JSONException: Unparsable JSON string:
at app//org.skyscreamer.jsonassert.JSONParser.parseJSON(JSONParser.java:56)
at app//org.skyscreamer.jsonassert.JSONCompare.compareJSON(JSONCompare.java:50)
,,,
当我将 ObjectMapper().writeValueAsString 更改为用于测试响应内容的 jsonpath 时,存在相同的异常。
请告诉我为什么抛出此异常,谢谢。
ps) 其他
UsersController
@RequiredArgsConstructor
@RestController
public class UsersController extends BaseController {
private final UsersService usersService;
@PostMapping("api/users/save")
public ResponseEntity<?> save (@RequestBody UsersSaveRequestDto requestDto) {
return sendResponseHttpByJson(usersService.save(requestDto));
}
@PostMapping("api/users/login")
public ResponseEntity<?> login (@RequestBody UsersLoginRequestDto requestDto) {
return sendResponseHttpByJson(usersService.login(requestDto));
}
@GetMapping("api/users/checkUserExist/{usersId}")
public ResponseEntity<?> checkUserExist (@PathVariable String usersId) {
return sendResponseHttpByJson(usersService.findByUsersId(usersId));
}
}
UsersService
package com.ReRollBag.service;
import com.ReRollBag.auth.JwtTokenProvider;
import com.ReRollBag.domain.dto.UsersLoginRequestDto;
import com.ReRollBag.domain.dto.UsersLoginResponseDto;
import com.ReRollBag.domain.dto.UsersResponseDto;
import com.ReRollBag.domain.dto.UsersSaveRequestDto;
import com.ReRollBag.domain.entity.Users;
import com.ReRollBag.exceptions.usersExceptions.UsersIdAlreadyExistException;
import com.ReRollBag.repository.UsersRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Log4j2
@RequiredArgsConstructor
@Service
public class UsersService {
private final UsersRepository usersRepository;
private final PasswordEncoder passwordEncoder;
private final JwtTokenProvider jwtTokenProvider;
@Transactional
public UsersResponseDto save(UsersSaveRequestDto requestDto) {
Users users = requestDto.toEntity();
String encryptedPassword = passwordEncoder.encode(users.getPassword());
users.setPassword(encryptedPassword);
usersRepository.save(users);
return new UsersResponseDto(users);
}
public UsersResponseDto findByUsersId (String usersId) {
Users users = usersRepository.findByUsersId(usersId);
if (users == null) throw new IllegalArgumentException("Users is not Exists");
return UsersResponseDto.builder()
.users(users)
.build();
}
public Boolean checkUserExist (String usersId) throws UsersIdAlreadyExistException {
if (usersRepository.existsByUsersId(usersId)) throw new UsersIdAlreadyExistException();
return true;
}
public UsersLoginResponseDto login (UsersLoginRequestDto requestDto) {
String targetUsersId = requestDto.getUsersId();
Users targetUsers = usersRepository.findByUsersId(targetUsersId);
if (targetUsers == null) throw new IllegalArgumentException("Users Id is wrong");
if (!passwordEncoder.matches(requestDto.getPassword(), targetUsers.getPassword())) {
throw new IllegalArgumentException("Password is wrong");
}
if (jwtTokenProvider == null) log.error("jwtTokenProvider is NULL!");
String accessToken = jwtTokenProvider.createAccessToken(requestDto.getUsersId());
String refreshToken = jwtTokenProvider.createRefreshToken(requestDto.getUsersId());
return UsersLoginResponseDto.builder()
.accessToken(accessToken)
.refreshToken(refreshToken)
.build();
}
}
由于 JsonException,无法测试 http 响应内容的 json 解析测试。 我认为初始化 mockMvc 有问题。 请让我知道为什么会引发此异常。
【问题讨论】:
标签: java spring-boot unit-testing mockito junit5