使用Testcontainer PubSub模拟器测试GCP PubSub时遇资源未找到问题
解决Testcontainer PubSub模拟器下Publisher实现的NOT_FOUND错误
以下是针对你遇到问题的排查和解决步骤:
提前创建Topic
GCP生产环境PubSub支持自动创建Topic(权限允许的情况下),但Testcontainer PubSub模拟器没有这个特性。你的业务代码在生产环境依赖了自动创建逻辑,但测试时模拟器里不存在目标Topic,就会抛出NOT_FOUND错误。
解决方法:在测试初始化阶段,用PubSub Admin客户端提前创建test-topic:@BeforeEach void setupPubSubResources() { String emulatorEndpoint = pubsubContainer.getEmulatorEndpoint(); System.setProperty("PUBSUB_EMULATOR_HOST", emulatorEndpoint); // 初始化Admin客户端 PubSub pubSub = PubSubOptions.newBuilder() .setHost(emulatorEndpoint) .setCredentialsProvider(FixedCredentialsProvider.create(NoCredentials.getInstance())) .build().getService(); // 确保Topic存在 pubSub.createTopic(TopicName.of("test-project-id", "test-topic")); }验证Publisher的模拟器配置
你自己实现的Publisher可能没有正确指向模拟器地址,而是默认走了生产环境的PubSub端点。要手动指定模拟器的Endpoint和无凭据配置:Publisher publisher = Publisher.newBuilder(TopicName.of("test-project-id", "test-topic")) .setChannelProvider( PublisherStubSettings.defaultGrpcTransportProviderBuilder() .setEndpoint(pubsubContainer.getEmulatorEndpoint()) .setCredentialsProvider(FixedCredentialsProvider.create(NoCredentials.getInstance())) .build()) .build();检查项目ID一致性
测试中使用的项目ID必须和创建Topic时的项目ID完全匹配。如果业务代码硬编码了生产环境的项目ID,而测试用了不同的ID,模拟器会找不到对应的Topic。确认异步发布的等待逻辑
错误中的ExecutionException是异步操作的包装异常,要确保测试代码等待发布请求完成后再结束,避免因为客户端提前关闭导致请求失败:ApiFuture<String> publishFuture = publisher.publish(PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("test-data")).build()); // 同步等待发布完成 String messageId = ApiFutures.getUnchecked(publishFuture);
内容的提问来源于stack exchange,提问作者JackTheKnife
相关产品推荐
相关产品推荐

