如何在没有继承的情况下在我的测试中共享@MockBeans和mock方法?

时间:2018-03-06 20:42:06

标签: spring inheritance junit mocking integration-testing

我有一个基本测试场景,将由其他集成测试使用。此方案包括一些用于外部集成的模拟bean(@MockBean)。

今天,我在集成测试类中有类似的东西:

@SpringBootTest
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OrderIT {

准备我的集成测试的字段和注释:

private MockMvc mockMvc;

@Autowired
private WebApplicationContext wac;

@Autowired
private ObjectMapper mapper;

@MockBean
private SomeGateway someGateway;

@MockBean
private SomeRabbitMqService someRabbitMqService ;

@MockBean
private AnotherRabbitMqService anotherRabbitMqService;

@MockBean
private SomeIntegrationService someIntegrationService ;

@MockBean
private Clock clock;

@Before
public void setup() {
    //some methods mocking each service above, preparing mockMvc, etc
}

此方案是使用MockMvc并在系统中创建主要功能Order所必需的。通过在Rest API中调用POST方法创建此Order,将order保存在内存数据库中。

即使这样运作良好,我还需要在其他测试中重复包含这些@MockBean和某些@Autowired的代码块,因为Order基本方案,将产品添加到订单,设置要传递的地址等。每个方案都有不同的集成测试,但所有方案都需要Order

那么,如何分享" MockBeans"以及在我的集成测试中模仿它们的方法?我在测试中确实有使用继承的糟糕经历,我真的想尝试不同的方法。

2 个答案:

答案 0 :(得分:1)

我最终使用Spring profiles

我创建了一个用@Profile("test")注释的配置类,并在那里创建了模拟bean。像:

@Profile("test")
@Configuration
public class MyMockConfiguration {

    @Bean
    public SomeService someService() {
        SomeService someService = mock(SomeService .class);
        // mocked methods and results
        return someService ;
    }

在Test类中:

@ActiveProfiles("test")
@SpringBootTest
@WebAppConfiguration
@RunWith(SpringRunner.class)
public class MyControllerIT {

如果某个集成测试需要覆盖配置文件中的当前模拟实现,那么测试只需要在类上声明@MockBean并像往常一样继续模拟。

我还没有决定test是否是一个好名字,因为对我而言更有意义的是通过" context"来模拟配置。因此,我可以使用test而不是在配置文件名称上使用通用名称createOrder,并使用不同的配置文件,每个配置文件具有不同的名称和不同的模拟:createOrder,{{ 1}}。

答案 1 :(得分:0)

我相信 @ContextConfiguration 是为此目的而创建的:https://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles