在集成测试中覆盖 bean

新手上路,请多包涵

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

我怎样才能确保来自 TestConfig 的那个是被使用的那个?

这是我的配置文件:

 @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)
    }
}

原文由 mvlupan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 802
2 个回答

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

对评论的反应:

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

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

原文由 luboskrnac 发布,翻译遵循 CC BY-SA 3.0 许可协议

1.可以使用 @Primary 注解:

 @Configuration
public class MockRestTemplateConfiguration {

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

顺便说一句,我写了 一篇关于伪造 Spring bean 的博文

2. 但我建议看一下 Spring RestTemplate testing support 。这将是一个简单的例子:

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

原文由 luboskrnac 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题