【问题标题】:Mockito and expected the exceptionMockito 并期望异常
【发布时间】:2016-12-23 14:38:02
【问题描述】:

我从我的控制器创建测试,它必须将重定向 url 返回到“/register/duplicate”。但是当我执行该操作时,我会遇到异常,例如 DataIntegrityViolationException。控制器应该捕捉到这个异常,但没有捕捉到

它是如何工作的?我能做的,对控制器来说,发生了一个异常并以“catch”原因执行代码,将重定向到/register/duplicate

测试:

@Test
public void testRegisterPageLogic_Duplicate() throws Exception {
    expectedUser = new User("Jorg", "Brush");
    UserService mockService = mock(UserService.class);

    userService.add(expectedUser);

    when(mockService.add(expectedUser)).thenCallRealMethod();

    registerController = new RegisterController(mockService);
    mockMvc = standaloneSetup(registerController).build();

    mockMvc.perform(post("/register")
            .param("hide", "up")
            .param("username", expectedUser.getUsername())
            .param("password", expectedUser.getPassword()))
            .andExpect(redirectedUrl("/register/duplicate"));

    Mockito.verify(mockService, atLeastOnce()).add(expectedUser);

    userService.remove(userService.findUser("Jorg").getUserId());
}

控制器方法:

@RequestMapping(method = POST)
public String register(@RequestParam("hide") String hide,
                       @RequestParam("username") String username,
                       @RequestParam("password") String password) {

    if (hide.equals("up")) {
        try {
            userService.add(new User(username, password));
        } catch (DataIntegrityViolationException e) {
            return "redirect:/register/duplicate";
        }
    }
    User user = userService.findUser(username);
    if (user == null) {
        return "redirect:/register/notExists";
    }
    UserSession.setUser(user);
    UserSession.setId(user.getUserId());
    return "redirect:/notes/" + UserSession.getUser().getUsername();
}

【问题讨论】:

  • 你的问题我已经看了两遍,抱歉我不明白你想要什么
  • 你是在问如何使用 mockito 让一些 mock 抛出异常??
  • 连我都答不上来。
  • @RC。是的,有些人喜欢这样。我想,当执行方法userService.add()时,抛出异常,它在catch case catch (DataIntegrityViolationException e) {...}中捕获这个异常

标签: java junit mockito junit4


【解决方案1】:

让我们试着简化一下,如果代码是:

try {
    userService.add(new User(username, password));
} catch (DataIntegrityViolationException e) {
    return "redirect:/register/NOT-OK";
}
return "redirect:/register/OK";

你想测试两个分支,然后

@RunWith(MockitoJUnitRunner.class) // for @Mock
class TheTest {

    @Mock
    UserService mockService;

    MockMvc mockMvc;    

    @Before
    public void setup() {        
        RegisterController registerController = new RegisterController(mockService);
        mockMvc = standaloneSetup(registerController).build();
    }

    @Test
    public void testOK() throw Exception {
        // mockService does nothing by default

        mockMvc.perform(post("/register"))
               .andExpect(view().name("/register/OK"));

        Mockito.verify(mockService).add(Matchers.any(User.class));
    }

    @Test
    public void testNotOk() {
        Mockito.when(mockService.add(Matchers.any(User.class))
               .thenThrow(new DataIntegrityViolationException()); // adjust DataIntegrityViolationException constructor args if required.

        // now mockService throw a DataIntegrityViolationException when mockService#add(User) is called

        mockMvc.perform(post("/register"))
               .andExpect(view().name("/register/NOT-OK"));

        Mockito.verify(mockService).add(Matchers.any(User.class));
    }
}

【讨论】:

  • 因为new User() 每次都会给你一个全新的用户
【解决方案2】:

要在 Mockito 中引发异常,您不需要调用真实方法。您可以使用此代码:

when(mockService.add(expectedUser)).thenThrow(DataIntegrityViolationException.class)

【讨论】:

  • 我试过了,但不同的是,新的 DataIntegrityViolationException("")。但是当在控制器中执行此方法mockService.add(expectedUser) 时,此 try{}catch 将被忽略并继续运行。然后,我在测试中发现一个错误:预期:/register/duplicate 实际:/register/notExists
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
相关资源
最近更新 更多