gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:31:05 25 4
gpt4 key购买 nike

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

@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 文档进行了尝试: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
}
}

此解决方案效果不佳。如果两个测试单独运行,则两个测试通过,但是同时运行它们会导致第二个测试失败(这里的顺序是相关的,所以如果第二个测试排在最前面,它就会通过)。

同时运行测试和调试时,我看到一旦在第一个测试中按预期调用了两个模拟,对模拟的所有后续调用都会导致 nullfalse 分别尽管指定了其他内容。

如何在集成测试中模拟通过 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-test 的一部分。

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

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

关于java - Micronaut:在 Spock 中模拟工厂创建的 Bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55634575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com