繁体   English   中英

使用Mockito在Spring中测试方法Controller

[英]Testing method Controller in Spring with mockito

@PostMapping(path = "/add")
public @ResponseBody ResponseEntity<String> addAccount(@RequestBody Account account) {
    if (account != null && account.getUserName() != null && account.getUserPass() != null) ) {
        if (accountRepository.countUserName(account.getUserName()) > 0) {
            return new ResponseEntity<String>("Account",HttpStatus.BAD_REQUEST);
        }
        account.setUserPass(bCryptPasswordEncoder.encod(account.getUserPass()));
        accountRepository.AccountSaveTo(account);
        return new ResponseEntity<String>("Saved",HttpStatus.OK);
    }
    return new ResponseEntity<String>("Invalid",HttpStatus.BAD_REQUEST);
}

我必须测试AccountController此方法。 我正在使用Mockito库在Spring中测试该方法。 如何测试此方法? 我之前编写了以下单元测试:

@Test
public void shouldSaveAccountToDb() {
    Account acc = new Account();
    acc.setUser(this.user);
    acc.setEmail(this.mail);
    String account = this.accountController.addAccount(this.user, this.mail);
    verify(this.accountRepepetytory)).save(Mockito.refEq(acc, new String[0]));
    Assert.assertThat(account, CoreMatchers.is("Account"));
}

但是此方法得到了改进和更改,因此我必须编写一个新的单元测试,但是我不知道如何以及从哪里开始。 即使使用伪代码,您也可以提供帮助吗?

一旦我们谈论了Mockito,我们必须牢记我们只是在尝试单元测试,对吗? 我的意思是,没有相关的集成等等。

我对您的测试有些困惑,因为您发布了一些类(我想它是您的控制器),但是您希望从AccountRepository调用某些方法,但是即使您调用的是观察正在发送的参数的引用,而不是价值观本身。

就个人而言,探索我从您的测试中了解的内容,我会这样做:

@RunWith(MockitoJUnitRunner.class)
public class AccountControllerTest {
   @Spy
   @InjectMocks
   private AccountController controller;

   @Mock
   private AccountRepository repository;

   @Test
   public void shouldSaveAccountToDb() {
      Account acc = new Account();
      acc.setUser(this.user);
      acc.setEmail(this.mail);

      doReturn(0).when(repository).countUserName(this.user);
      doReturn("Saved").when(repository).accountSaveTo(acc);

      ResponseEntity<String> result = controller.addAccount(acc);

      verify(repository, times(1)).accountSaveTo(acc);
      Assert.assertEquals("Saved", result.getEntity());

}

解释我做了什么:

根据您的测试名称,我想您仅希望将其保存在数据库中才能获得正确的结果。 “帐户”不是在保存到数据库中时返回的,而是在该帐户中已经存在时返回的,因此您的测试命名未反映其实际作用。

考虑到这一点,我确定了对该测试的期望,以正确反映它在做什么。

之后,我为控制器使用了@Spy批注( 为带注释的类 输入了实际方法 ),为外部组件使用了 @Mock没有为带注释的类输入了实际方法 )。 @InjectMocks将所有模拟添加到带注释的实例。

一旦我们有了要测试的组件(单元),就可以从外部组件中删除结果,如下所示:

doReturn({expected_return}).when({mock}).{method_name}({parameters});

现在,当您运行测试时,代码将回答您在该@Spy组件中为该组件配置的内容,现在,您只是在测试单元并访问实际方法以覆盖其将来。

我希望我能帮助您,先生:)

使用经典的单元测试来测试Spring控制器是毫无价值的,因为Spring依赖于控制器周围的许多魔术。 通过使用Spring MVC Test框架(以前称为MockMVC),您可以获得更具表现力和可靠性的测试。 它允许您在控制器上触发虚拟请求并基于虚拟响应进行断言(虚拟意味着不涉及网络流量,所有请求,会话和响应都是非常智能的模拟)。

测试示例如下所示:

@Test
void getAccount() throws Exception {
    this.mockMvc.perform(get("/accounts/1").accept(
        MediaType.parseMediaType("application/json;charset=UTF-8"))
    )
    .andExpect(status().isOk())
    .andExpect(content().contentType("application/json"))
    .andExpect(jsonPath("$.name").value("Lee"));
}

为此,您可以使用MockMvc lib

另外,请尝试以下教程: https : //memorynotfound.com/unit-test-spring-mvc-rest-service-junit-mockito/

使用此技术的代码示例:

@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext(classMode=ClassMode.AFTER_CLASS, methodMode=MethodMode.BEFORE_METHOD)
@AutoConfigureTestDatabase
public class AccountRestTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void testPostNewEntity() throws Exception {
        Account account = new Account("dummy");
        MvcResult result = mvc.perform(MockMvcRequestBuilders.post("/add")
                .content(ClassToStringUtils.parse(account)).contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().is(HttpStatus.CREATED.value()))
                .andReturn();
    }
}

//编辑

ClassToStringUtils.parse(Object obj)只是将对象解析为json格式的String。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM