Spring boot 单元测试Spring Boot应用程序服务层

Spring boot 单元测试Spring Boot应用程序服务层,spring-boot,unit-testing,kotlin,Spring Boot,Unit Testing,Kotlin,我对SpringBoot提供的测试功能和实用程序有点困惑 我正在项目中使用springbootstarter测试,我想在没有数据库连接的情况下对我的服务进行单元测试 目前,我正在使用@WebMvcTest作为contoller测试套件,而@SpringBootTest作为所有其他测试类 但我在某个地方读到,@SpringBootTest只用于集成测试 阅读时,我不明白建议的服务方法是什么。我应该只在与回购协议集成的情况下测试它们吗 更新 这是我的一项服务的一个测试类的摘录: @TestInsta

我对SpringBoot提供的测试功能和实用程序有点困惑

我正在项目中使用
springbootstarter测试
,我想在没有数据库连接的情况下对我的服务进行单元测试

目前,我正在使用
@WebMvcTest
作为contoller测试套件,而
@SpringBootTest
作为所有其他测试类

但我在某个地方读到,
@SpringBootTest
只用于集成测试

阅读时,我不明白建议的服务方法是什么。我应该只在与回购协议集成的情况下测试它们吗

更新

这是我的一项服务的一个测试类的摘录:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
internal class SignupServiceTest(
        @Autowired val signupService: SignupService
) {
    @MockkBean
    lateinit var userRepository: UserRepository

    @Test
    fun `should return exception if username already used`() {
        every { userRepository.findByUsername("registered-user") } returns fakeUser(username = "registered-user")

        assertThatThrownBy {
            signupService.createNewAccount(fakeSignupForm(username = "registered-user"))
        }.isExactlyInstanceOf(UsernameNotAvailableException::class.java)
    }

    // ... other tests

}

尝试使用mockito模拟对数据库的调用,或者使用h2数据库进行测试

您应该更倾向于实现单元测试来测试您的业务逻辑(在没有Spring的情况下运行的测试,普通JUnit测试),而不是集成测试(启动Spring容器的测试,
@SpringBootTest
)因为它们更轻,给你的反馈更快

引自

依赖项注入的一个主要优点是它应该使代码更容易进行单元测试。您可以使用new操作符实例化对象,甚至不涉及Spring。您还可以使用模拟对象而不是真实的依赖项

通常,您需要超越单元测试,开始集成测试(使用Spring ApplicationContext)。能够在不需要部署应用程序或连接到其他基础架构的情况下执行集成测试非常有用


使用
@SpringBootTest
进行单元测试有点过分了。因为这将启动整个应用程序上下文

为了测试单个(服务)类,我将使用
@RunWith(MockitoJUnitRunner.class)
,而不是
@Autowired
@MockBean
使用
@Mock
@InjectMocks
(如果使用构造函数注入,就不必使用它。哪个选项更好)

您仍然可以将
@Autowired
@ContextConfiguration
一起使用,并加载特定的类(如果没有太多可传递的依赖项)

如果您不想使用mock,那么您可以使用嵌入式数据库并使用
@DataMongoTest
@DataJpaTest
并使用Springboot测试功能


保持简单….

不,您应该通过模拟repo层来测试各个服务类。是的,您不应该使用将加载整个应用程序上下文的
@SpringbootTest
,这对于单元测试来说是不需要的。这正是我试图做的(我使用mock),但是仍然需要数据库连接……不必。把相关代码放进去,可能会比较容易理解suggest@pvpkiran我添加了一些代码,而不是springboottest使用
@RunWith(MockitoJUnitRunner.class)
,也不是
@Autowired
@MockBean
使用
@Mock
@InjectMocks
。我使用
@RunWith(MockitoJUnitRunner.StrictStubs.class)
进行所有服务单元测试,并模拟所有依赖项。它工作得很好,而且跑得很快。