编程语言
首页 > 编程语言> > java-Micronaut:在Spock中模拟工厂创建的Bean

java-Micronaut:在Spock中模拟工厂创建的Bean

作者:互联网

我需要执行从Micronaut到Spring应用程序的远程调用.为了创建必要的bean,我创建了一个Factory:

@Factory
public class RemotingConfig {

  @Bean
  @Singleton
  public OfferLeadService offerLeadService(@Value("${offer.server.remoting.base.url}") 
                                                 String offerRemotingBaseUrl) {
    HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
    invoker.setHttpInvokerRequestExecutor(new SimpleHttpInvokerRequestExecutor());
    invoker.setServiceUrl(offerRemotingBaseUrl + OfferLeadService.URI);
    invoker.setServiceInterface(OfferLeadService.class);
    invoker.afterPropertiesSet();
    return (OfferLeadService) invoker.getObject();
  }

  @Bean
  @Singleton
  public APIKeyService apiKeyService(@Value("${offer.server.remoting.base.url}") 
                                           String offerRemotingBaseUrl) {
    HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean();
    invoker.setHttpInvokerRequestExecutor(new SimpleHttpInvokerRequestExecutor());
    invoker.setServiceUrl(offerRemotingBaseUrl + APIKeyService.URI);
    invoker.setServiceInterface(APIKeyService.class);
    invoker.afterPropertiesSet();
    return (APIKeyService) invoker.getObject();
  }
}

在我的Spock集成测试中,我需要模拟这些bean,我根据Micronaut docs进行了尝试:https://docs.micronaut.io/latest/guide/index.html#replaces

这导致了这样的测试:

@MicronautTest
class StackoverflowSpecification extends Specification {

  @Inject
  AuthorizedClient authorizedClient

  @Inject
  UnauthorizedClient unauthorizedClient

  @Inject
  OfferLeadService offerLeadService

  @Inject
  APIKeyService apiKeyService

  @Factory
  @Replaces(factory = RemotingConfig.class)
  static class RemotingConfigTest extends Specification {

    @Singleton
    OfferLeadService offerLeadService() {
      return Mock(OfferLeadService)
    }

    @Singleton
    APIKeyService apiKeyService() {
      return Mock(APIKeyService)
    }
  }

  void "authenticated sessions request returns 200 ok"() {

    when:
    HttpResponse response = authorizedClient.getSession("AA-BB-CC")

    then:
    response.status == OK

    and: 'setup mock calls'
    1 * apiKeyService.find(_, _) >> buildApiKeyVO()
    1 * offerLeadService.containsHipHavingPostalCode(_, _) >> true
    0 * _
  }

  void "authenticated sessions request with wrong passphrase returns 403 forbidden"() {

    when:
    unauthorizedClient.getSessionWithWrongPassphrase("AA-BB-CC")

    then:
    HttpClientResponseException ex = thrown(HttpClientResponseException)

    then:
    ex.status == FORBIDDEN

    and: 'setup mock calls'
    1 * apiKeyService.find(_, _) >> buildApiKeyVO()
    1 * offerLeadService.containsHipHavingPostalCode(_, _) >> false
    0 * _
  }

  private static APIKeyVO buildApiKeyVO() {
    APIKeyVO key = new APIKeyVO()
    key.setId(1L)
    key.setValue("123")
    key.setEnabled(true)
    key.setRoles(List.of("ROLE_STANDARD"))
    key.setValidUntil(Instant.now().plus(100, ChronoUnit.DAYS))
    key.setDescription("CBC App")
    key.setAccountId("CBC")
    return key
  }
}

此解决方案无法正常工作.如果两个测试孤立地运行,则通过,但是同时运行这两个测试,则导致第二个测试失败(顺序与此处相关,因此,如果第二个测试位于最前面,则将是一次通过).

在同时运行测试和调试时,我看到一旦在第一个测试中按预期方式调用了两个模拟,那么尽管指定了其他内容,但随后对模拟的所有调用分别导致null和false.

我该如何模拟在集成测试中通过RemotingConfig指定的两个bean?

解决方法:

您没有正确使用@Replaces批注.工厂成员并不是要自己使用,而是要进一步限定要替换的类型.

  @Factory
  static class RemotingConfigTest extends Specification {

    @Singleton
    @Replaces(bean = OfferLeadService.class, factory = RemotingConfig.class)
    OfferLeadService offerLeadService() {
      return Mock(OfferLeadService)
    }

    @Singleton
    @Replaces(bean = APIKeyService.class, factory = RemotingConfig.class)
    APIKeyService apiKeyService() {
      return Mock(APIKeyService)
    }
  }

编辑:以上仍然适用,但是您希望在测试执行之间重置模拟.上面的代码不会发生这种情况.您需要使用@MockBean批注,它是micronaut-test的一部分.

@MockBean(OfferLeadService.class)
OfferLeadService offerLeadService() {
    return Mock(OfferLeadService)
}

@MockBean(APIKeyService.class)
APIKeyService apiKeyService() {
    return Mock(APIKeyService)
}

标签:mocking,spock,micronaut,spring,java
来源: https://codeday.me/bug/20191108/2005787.html