在没有启动应用程序的情况下在 SpringBoot 中编写单元测试

Posted

技术标签:

【中文标题】在没有启动应用程序的情况下在 SpringBoot 中编写单元测试【英文标题】:Write Unit test in SpringBoot Without start application 【发布时间】:2021-02-23 01:15:18 【问题描述】:

正在 springBoot 中开发微服务。我正在为服务和 DAO 层编写单元测试。当我使用 @SpringBootTest 时,它会在构建时启动应用程序。但它不应该启动应用程序 当我运行单元测试时。我使用了 @RunWith(SpringRunner.class),但无法在 junit 类中 @Autowired 类实例。如何配置不应该启动应用程序的 junit 测试类以及如何在 junit 类中 @Autowired 类实例。

【问题讨论】:

【参考方案1】:

如果您不想启动完整的应用程序,请使用 MockitoJUnitRunner 进行 JUnit5 测试。

任何服务、存储库和接口都可以通过@Mock 注解进行模拟。

@InjectMocks 用于需要测试的 Class 对象。

这是一个例子。

@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class AServiceTest 
    
    @InjectMocks
    AService aService;
    
    @Mock
    ARepository aRepository;
    
    @Mock
    UserService userService;
    
    
    @Before
    public void setUp() 
        // MockitoAnnotations.initMocks(this);
        // anything needs to be done before each test.
    
    
    @Test
    public void loginTest() 
        Mockito.when(aRepository.findByUsername(ArgumentMatchers.anyString())).thenReturn(Optional.empty());
        String result = aService.login("test");
        assertEquals("false", result);
    

【讨论】:

要求应该是连接到数据库以获取记录。如果模拟对象,我们无法获得实时数据。这可能使用@ContextConfiguration @user3410249 如果你想执行单元测试,你可以模拟数据库记录本身。由于 MockitoJUnitRunner 是在不运行应用程序或外部数据库的情况下进行测试的最快方式。选项是您使用 Mockito.when(...).thenReturn() 从数据库返回模拟记录,这是单元测试的更好方法。但是如果你想实时连接到数据库,你的应用程序就会启动。 谢谢。我更明白了。【参考方案2】:

使用 Spring Boot,您可以启动 a sliced version of your application 进行测试。这将创建一个 Spring Context,它只包含相关的 bean 的一个子集,例如仅适用于您的 Web 层(控制器、过滤器、转换器等):@WebMvcTest

有一个类似的注释可以帮助您测试您的 DAO,因为它只填充 JPA 和数据库相关的 bean(例如 EntitiyManagerDatasource 等):@DataJpaTest

如果您想自动装配一个不属于由上述注释创建的 Spring 测试上下文的 bean,您可以使用 @TestConfiguration 手动将您喜欢的任何 bean 添加到测试上下文中

@WebMvcTest(PublicController.class)
class PublicControllerTest 

  @Autowired
  private MockMvc mockMvc;

  @TestConfiguration
  static class TestConfig 

    @Bean
    public EntityManager entityManager() 
      return mock(EntityManager.class);
    

    @Bean
    public MeterRegistry meterRegistry() 
      return new SimpleMeterRegistry();
    

  

【讨论】:

【参考方案3】:

根据您的测试设置,如果您想要自动装配模拟但“真实的东西”,您可以简单地注释您的测试类以包含您需要的类(加上它们的传递必要时依赖)

例如:

@SpringJUnitConfig( SimpleMeterRegistry.class )

@SpringJUnitConfig
@Import( SimpleMeterRegistry.class )

@SpringJUnitConfig
@ContextConfiguration(classes =  SimpleMeterRegistry.class )

在此处Spring Boot Web Data JDBC allin 中查看基于 JUnit5 的工作示例。

【讨论】:

以上是关于在没有启动应用程序的情况下在 SpringBoot 中编写单元测试的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有可启动应用程序的情况下在 Apple Watch 上实现动态通知?

如何在没有 WebRTC 的情况下在 HTML5 中启动前置摄像头?

在没有用户登录的情况下在 Windows 启动时运行脚本

如何在没有控制台窗口的情况下在 Windows 上启动最新的 Jupyter QtConsole

在没有全屏的情况下在 UIWebView 中播放 Youtube 视频

如何在没有浏览器的情况下在 python 中使用 Tor?