在集成测试中覆盖 Bean

对于我的Spring-Boot应用程序,我通过一个@Configuration文件提供了一个RestTemplate,所以我可以添加合理的默认值(例如超时)。对于我的集成测试,我想模拟 RestTemplate,因为我不想连接到外部服务 - 我知道期望得到什么响应。我尝试在集成测试包中提供不同的实现,希望后者将覆盖实际的实现,但是检查日志则相反:真正的实现覆盖测试实现。

如何确保测试配置中的那个是使用的那个?

这是我的配置文件:

@Configuration
public class RestTemplateProvider {

    private static final int DEFAULT_SERVICE_TIMEOUT = 5_000;

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate(buildClientConfigurationFactory());
    }

    private ClientHttpRequestFactory buildClientConfigurationFactory() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(DEFAULT_SERVICE_TIMEOUT);
        factory.setConnectTimeout(DEFAULT_SERVICE_TIMEOUT);
        return factory;
    }
}

集成测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@WebAppConfiguration
@ActiveProfiles("it")
public abstract class IntegrationTest {}

测试配置类:

@Configuration
@Import({Application.class, MockRestTemplateConfiguration.class})
public class TestConfiguration {}

最后是 MockRestTemplateConfiguration

@Configuration
public class MockRestTemplateConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        return Mockito.mock(RestTemplate.class)
    }
}

答案 1

从Spring Boot 1.4.x开始,有一个选项可以使用注释来伪造Spring bean。@MockBean

对评论的反应:

要将上下文保留在缓存中,请不要使用 ,而是使用,它将创建单独的上下文,而它将在缓存中保留默认上下文。Spring会将两者(或您拥有的上下文数量)保留在缓存中。@DirtiesContext@ContextConfiguration(name = "contextWithFakeBean")

我们的构建是这样的,大多数测试都使用默认的非poluted配置,但是我们有4-5个伪造bean的测试。默认上下文被很好地重用


答案 2

1. 您可以使用注释:@Primary

@Configuration
public class MockRestTemplateConfiguration {

    @Bean
    @Primary
    public RestTemplate restTemplate() {
        return Mockito.mock(RestTemplate.class)
    }
}

顺便说一句,我写了关于伪造春豆的博客文章

2. 但我建议看看Spring RestTemplate测试支持。这是一个简单的例子:

  private MockRestServiceServer mockServer;

  @Autowired
  private RestTemplate restTemplate;

  @Autowired
  private UsersClient usersClient;

  @BeforeMethod
  public void init() {
    mockServer = MockRestServiceServer.createServer(restTemplate);
  }

  @Test
  public void testSingleGet() throws Exception {
    // GIVEN
    int testingIdentifier = 0;
    mockServer.expect(requestTo(USERS_URL + "/" + testingIdentifier))
      .andExpect(method(HttpMethod.GET))
      .andRespond(withSuccess(TEST_RECORD0, MediaType.APPLICATION_JSON));


    // WHEN
    User user = usersClient.getUser(testingIdentifier);

    // THEN
    mockServer.verify();
    assertEquals(user.getName(), USER0_NAME);
    assertEquals(user.getEmail(), USER0_EMAIL);
  }

更多例子可以在我的Github存储库中找到 这里


推荐