在集成测试中覆盖bean

9 浏览
0 Comments

在集成测试中覆盖bean

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

我该如何确保使用 TestConfig 中的 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 {}

TestConfiguration 类:

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

最后是 MockRestTemplateConfiguration

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

admin 更改状态以发布 2023年5月24日
0
0 Comments

1.
你可以使用@Primary 注解:

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

顺便说一句,我写了一篇关于模拟Spring bean的博客文章

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仓库中找到

0
0 Comments

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

评论反应:

为了保留缓存中的上下文,请不要使用@DirtiesContext,而是使用@ContextConfiguration(name = "contextWithFakeBean"),它将创建一个单独的上下文,同时将默认上下文保留在缓存中。 Spring将保留(或者您拥有多少个上下文)。

我们的构建方式如此,其中大多数测试都使用默认的非污染配置,但我们有4-5个测试正在伪造bean。默认上下文被很好地重用。

0