![](/img/trans.png)
[英]How to resolve Uncaught exception thrown by REST service: Unrecognized field “input”
[英]How to mock a exception in rest controller where the exception is thrown from a service
我正在為 Spring 啟動中的 rest Controller 編寫測試用例。
為了提供有關該問題的一些背景信息,我無法模擬在 controller 層的服務中引發的異常。
我正在使用 PowerMokito 編寫測試用例。
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserApiController.class)
public class UserApiControllerTest {
/* private MockMvc mockMvc;*/
@Mock
GenericService genericService;
@Mock
UserService userService;
@Mock
UserRoleService userRoleService;
@Mock
MessageService messageService;
@Mock
CurrentUserService currentUserService;
@Mock
UserRepository userRepository;
@Mock
UserRoleRepository userRoleRepository;
@InjectMocks
UserApiController userApiController;
@Before
public void setup() {
// this must be called for the @Mock annotations above to be processed
MockitoAnnotations.initMocks(this);
//Set up mocking for repository methods
}
@Test(expected = DuplicateUserEmailException.class)
public void saveUserByEmailFailure() throws Exception {
HashMap mockUser = new HashMap<String,Object>();
mockUser.put("email","test_dy1@gmail.com");
String user = new ObjectMapper().writeValueAsString(mockUser);
doThrow(new DuplicateUserEmailException()).
when(userService).saveUserByEmailId(any());
userApiController.saveUserByEmailId(user);
}
請在下面找到 controller 的詳細信息。
@RequestMapping(value = "/save_user_by_email", method = RequestMethod.POST)
public String saveUserByEmailId(@RequestParam("user") String user) throws Exception {
ObjectMapper mapper = new ObjectMapper();
HashMap<String, Object> userJson = new HashMap<String, Object>();
userJson = mapper.readValue(user, new TypeReference<Map<String, Object>>(){});
JsonObjectBuilder responseBuilder = Json.createObjectBuilder();
try {
userService.saveUserByEmailId(userJson);
responseBuilder.add("success", true).add("code", genericService.getSuccessCode()).add("message",
userJson.containsKey("id") ? messageService.getMessage("message.success.update")
: messageService.getMessage("message.success.create"));
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
if(exception instanceof DuplicateUserEmailException)
throw new DuplicateUserEmailException();
}
return responseBuilder.build().toString();
}
最后,我解決了。 如果您有疑問,請找到下面的代碼並發表評論。
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserApiController.class)
public class UserApiControllerTest {
private MockMvc mockMvc;
@Mock
GenericService genericService;
@Mock
UserService userService;
@Mock
UserRoleService userRoleService;
@Mock
MessageService messageService;
@Mock
CurrentUserService currentUserService;
@InjectMocks
ApiExceptionHandlerAdvice apiExceptionHandlerAdvice;
@Mock
UserRepository userRepository;
@Mock
UserRoleRepository userRoleRepository;
@InjectMocks
UserApiController userApiController;
@Before
public void setup(){
// MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(userApiController).setControllerAdvice(apiExceptionHandlerAdvice).build();
}
@Test
public void testAddDuplicateCustomer() throws Exception {
HashMap mockUser = new HashMap<String,Object>();
mockUser.put("email","test_dy1@gmail.com");
String user = new ObjectMapper().writeValueAsString(mockUser);
when(userService.saveUserByEmailId(any())).thenThrow(DuplicateUserEmailException.class);
when(messageService.getMessage(any())).thenReturn("200");
RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/api/save_user_by_email").param("user",user);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = result.getResponse();
assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus());
// assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus());
}
試試這樣:
PowerMockito.doThrow(new DuplicateUserEmailException()).
when(userService).saveUserByEmailId(any(String.class));
確保saveUserByEmailId
方法是 void 返回類型
可能您沒有將該模擬實例傳遞給 userApiController 真實實例。 這是模擬服務的一個非常常見的錯誤。 您是為此使用@InjectMocks ,還是手動構建 userApiController 實例? 您能否告訴我們您在上面的測試 class 中使用的注釋?
老實說,我建議只使用 Mockito ,因為使用 PowerMock 你可以模擬很多瘋狂的東西,而且它可以進行字節碼操作
使用 Mockito 這將如下所示:
doThrow(newRuntimeException()).when(paymentService).completePayment(any(), any(), any());
如果你想模擬網絡調用,請使用 WireMock,我們已經使用了很長時間,它為我們的測試包增加了很多價值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.