Java Micronaut:模拟工厂在斯波克创建的bean

Java Micronaut:模拟工厂在斯波克创建的bean,java,spring,mocking,spock,micronaut,Java,Spring,Mocking,Spock,Micronaut,我需要执行从Micronaut到Spring应用程序的远程调用。为了创建必要的bean,我创建了一个工厂: @工厂 公共类远程配置{ @豆子 @独生子女 public offerledService offerledService(@Value(${offer.server.remoting.base.url})) 字符串offerMotingBaseURL){ HttpInvokerProxyFactoryBean调用器=新的HttpInvokerProxyFactoryBean(); set

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

@工厂
公共类远程配置{
@豆子
@独生子女
public offerledService offerledService(@Value(${offer.server.remoting.base.url}))
字符串offerMotingBaseURL){
HttpInvokerProxyFactoryBean调用器=新的HttpInvokerProxyFactoryBean();
setHttpInvokerRequestExecutor(新的SimpleHttpInvokerRequestExecutor());
setServiceUrl(OfferMotingBaseURL+OfferLeadService.URI);
setServiceInterface(OfferLeadService.class);
invoker.afterPropertieSet();
return(OfferLeadService)invoker.getObject();
}
@豆子
@独生子女
公共APIKeyService APIKeyService(@Value(${offer.server.remoting.base.url}))
字符串offerMotingBaseURL){
HttpInvokerProxyFactoryBean调用器=新的HttpInvokerProxyFactoryBean();
setHttpInvokerRequestExecutor(新的SimpleHttpInvokerRequestExecutor());
setServiceUrl(offerRemotingBaseUrl+APIKeyService.URI);
setServiceInterface(APIKeyService.class);
invoker.afterPropertieSet();
return(APIKeyService)invoker.getObject();
}
}
在我的Spock集成测试中,我需要模拟这些bean,我根据Micronaut文档进行了尝试:

这导致了这样的测试:

@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
  }
}
这个解决方案效果不佳。如果这两个测试是单独运行的,那么这两个测试都会通过,但是,这会导致第二个测试失败(这里的顺序是相关的,因此如果第二个测试在顶部,那么它将是通过的)

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


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

您没有正确使用
@Replaces
注释。
factory
成员不是为了自己使用,而是为了进一步限定被替换的类型

  @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测试的一部分

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

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