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

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

【问题讨论】:

    标签: spring-boot junit


    【解决方案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 的工作示例。

      【讨论】:

        猜你喜欢
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-28
        • 2019-02-19
        • 2023-01-09
        相关资源
        最近更新 更多