用于 Spring Boot 休息控制器的 Junit

Posted

技术标签:

【中文标题】用于 Spring Boot 休息控制器的 Junit【英文标题】:Junit for Spring Boot Rest Controller 【发布时间】:2021-05-19 14:46:48 【问题描述】:

如何在 Spring Boot 中为下面的 RestController 编写有意义的 Junit

@GetMapping("/api")
    public String m2(String process ) 
        
        if( process.equalsIgnoreCase("Y"))
        
            jobs.start();
         else if(process.equalsIgnoreCase("N"))
        
            jobs.sendEmail();
        
    

【问题讨论】:

【参考方案1】:

在我看来一个写得好的单元测试应该简洁,能够覆盖大部分(如果不是全部)代码分支,验证副作用,快速可靠易于阅读

假设您使用的是 JUnit 5Mockito,这样的事情可以实现上述所有功能:

@ExtendWith(MockitoExtension.class)
class MyControllerTests 

  @Mock
  private Jobs jobs;
  private MyController myController;

  @BeforeEach
  public void setUp() 
    myController = new MyControllerImpl(jobs);
  

  @Test
  void affirmativeProcessShouldStartJobs() 
    myController.m2("Y");
    verify(jobs).start();
  

  @Test
  void negativeProcessShouldSendEmail() 
    myController.m2("N");
    verify(jobs).sendEmail();
  

  //...add more tests here, eg.: what do you expect given null input?



P.S.:您可以明显提高此单元测试的可读性,因为您比我们任何人都更了解此代码在应用程序上下文中的含义。此外,您应该在 m2(String) 返回值上添加断言(我们无法从您的代码 sn-p 中看到)。

如果您想测试 API 是否实际公开并且可以通过 HTTP 联系,那将是 End-to-End 测试而不是单元测试,我建议不要使用 JUnit,而是使用考虑到这种 black-box 测试构建的东西,例如 Cucumber。

【讨论】:

感谢您的全面回答。您能告诉我`verify(jobs).start();` 是什么意思吗? Mockito.verify(mock).someMethod() 验证给定mocksomeMethod 已被调用一次。

以上是关于用于 Spring Boot 休息控制器的 Junit的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring boot、kotlin 和 junit 进行休息控制器单元测试

@CrossOrigin 不适用于 spring-boot-starter-web 2.5.2

Spring Boot 休息 API

为啥 Spring Boot 不在休息控制器上使用 @Primary Jackson ObjectMapper 进行 JSON 序列化?

Spring Boot在测试时嘲笑其他休息客户端

如何在Spring Boot中的所有测试用例之前只设置一次独立控制器?