如何在 Spring Boot 中用测试模拟替换 bean 以进行集成测试

Ser*_*nov 5 spring spring-boot

我有一个 spring 应用程序和这个应用程序的集成测试。我想用模拟豆替换豆。

我真正的豆子长这个样子

@Service
public class MyService {

}
Run Code Online (Sandbox Code Playgroud)

为了测试,我想更换它

@Service
public class TestMyService {

}
Run Code Online (Sandbox Code Playgroud)

我能想到的就是将配置文件用于不同的服务。例如:

@Service
@Profile("!test")
public class MyService implements IMyService {

}

@Service
@Profile("test")
public class TestMyService implements IMyService {

}
Run Code Online (Sandbox Code Playgroud)

然后我像这样自动装配 bean

@Autowired
private IMyService myService;
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Jak*_*cki 6

我个人的偏好是避免加载完整的上下文进行测试。因此,我喜欢我的测试集中在 Bean 的子集上。这通常意味着我概述了我在测试中使用的bean:

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = {TestMyService.class, OtherClassNeededForTesting.class}
)
public class DelaysProviderTest {

}
Run Code Online (Sandbox Code Playgroud)

如果需要更多配置,我倾向于准备一个单独的配置类进行测试:

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = MyTest.Cfg.class
)
public class MyTest {

    @Import({
        // .. some classes to import including TestMyService.class
    })
    @Configuration
    public static class Cfg {

    }

}
Run Code Online (Sandbox Code Playgroud)

当需要更多配置(或模拟)时,我使用测试配置来提供适当的模拟

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = MyTest.Cfg.class
)
public class MyTest {

    @Import({
        // .. some classes to import
    })
    @Configuration
    public static class Cfg {

        @Bean
        public IMyService service() {
            IMyService mock = Mockito.mock(IMyService.class);
            when(mock.someMethod()).thenReturn("some data");

            return mock;
        }

    }

}
Run Code Online (Sandbox Code Playgroud)


Grz*_*ski 6

春季启动具有@MockBean@SpyBean准确注解这个目的:

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-mocking-beans

声明很简单:

@MockBean
private MyService myService;
Run Code Online (Sandbox Code Playgroud)

Spring Boot 将在那里注入 Mockito 模拟而不是实际的 bean。

  • 它不会替换bean,只是创建另一个相同类型的mock bean并注入mock。嗯,在某些配置中这会带来重复的bean异常 (6认同)
  • 这是一个糟糕的答案。 (4认同)