如何在没有嵌入式服务器或新集群的情况下模拟 couchbase 进行验收测试?

Posted

技术标签:

【中文标题】如何在没有嵌入式服务器或新集群的情况下模拟 couchbase 进行验收测试?【英文标题】:How to mock couchbase for acceptance testing without embedded server or a new cluster just for that? 【发布时间】:2019-01-31 11:44:35 【问题描述】:

我正在对连接到 couchbase、elasticsearch 和 Kafka 的微服务进行验收测试。我不想使用任何嵌入式实例或任何测试集群。我希望能够模拟 couchbase 调用,但同时应该测试我编写的 N1QL 查询。

对于 elasticsearch,我正在使用 Wiremock 并模拟 REST 调用。但是对于 couchbase,我不知道客户端对数据库进行的其余调用的结构。

另外,我继续编写了一个测试用例。有了这个,我从错误消息中模拟了 couchbase 所做的所有 REST 调用。但是我看到 coouchbase 连接到 netty 频道,我该如何模拟该频道?

如果不是这样,有没有更好的方法来模拟 couchbase?

RxComputationScheduler- 3|ERROR||||c.c.c.d.i.n.u.c.D.rejectedExecution|181|Failed to submit a listener notification task. Event loop shut down?
java.util.concurrent.RejectedExecutionException: event executor terminated
at com.couchbase.client.deps.io.netty.util.concurrent.SingleThreadEventExecutor.reject(SingleThreadEventExecutor.java:796)
at com.couchbase.client.deps.io.netty.util.concurrent.SingleThreadEventExecutor.offerTask(SingleThreadEventExecutor.java:336)
at com.couchbase.client.deps.io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:329)
at com.couchbase.client.deps.io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:739)
at com.couchbase.client.deps.io.netty.util.concurrent.DefaultPromise.safeExecute(DefaultPromise.java:760)
at com.couchbase.client.deps.io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:428)
at com.couchbase.client.deps.io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:113)
at com.couchbase.client.deps.io.netty.channel.DefaultChannelPromise.setFailure(DefaultChannelPromise.java:87)
at com.couchbase.client.core.endpoint.AbstractEndpoint$3.call(AbstractEndpoint.java:381)
at com.couchbase.client.core.endpoint.AbstractEndpoint$3.call(AbstractEndpoint.java:374)
at rx.internal.operators.SingleOperatorOnErrorResumeNext$2.onError(SingleOperatorOnErrorResumeNext.java:69)
at rx.internal.operators.SingleTimeout$TimeoutSingleSubscriber$OtherSubscriber.onError(SingleTimeout.java:133)
at rx.Single$1.call(Single.java:477)
at rx.Single$1.call(Single.java:473)
at rx.Single.subscribe(Single.java:1979)
at rx.Single$18.call(Single.java:2518)
at rx.Single$18.call(Single.java:2505)
at rx.internal.operators.SingleTimeout$TimeoutSingleSubscriber.call(SingleTimeout.java:110)
at rx.internal.schedulers.EventLoopsScheduler$EventLoopWorker$2.call(EventLoopsScheduler.java:189)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

这是我遇到的错误。

【问题讨论】:

【参考方案1】:

另一个选项可能是使用 Testcontainers 模块。这里有一个用于 Couchbase:https://www.testcontainers.org/modules/databases/couchbase/

来自网站的构建存储桶的示例:

public class SomeTest 

    @Rule
    public CouchbaseContainer couchbase = new CouchbaseContainer()
             .withClusterAdmin("admin", "secret")
             .withNewBucket(DefaultBucketSettings.builder()
                        .enableFlush(true)
                        .name("bucket-name")
                        .password("secret")
                        .quota(100)
                        .type(BucketType.COUCHBASE)
                        .build());

    @Test
    public void someTestMethod() 
        Bucket bucket = couchbase.getCouchbaseCluster().openBucket("bucket-name");

        // ... interact with client as if using Couchbase normally
    

【讨论】:

【参考方案2】:

如果我决定这样做,我会在 SDK 级别进行模拟。创建您自己的对象版本,例如 Connection 和 Bucket 以及其他任何东西(我通常不使用 Java。)然后找一个地方注入这个备用数据库访问层以进行测试。这样,您就有自己的应用程序代码与您自己的模拟代码一起工作,让您完全控制。尝试在 SDK 对数据库进行的 HTTP 调用级别进行模拟,让我觉得过于依赖 Couchbase 未公开的晦涩材料。

【讨论】:

【参考方案3】:

您看过 CouchbaseMock 吗? https://github.com/couchbase/CouchbaseMock

来自自述文件:

CouchbaseMock 是一个测试服务器,实现了一些 memcached 一些 SDK(包括 C SDK)用于基本的协议 测试。虽然建议针对真实情况进行测试 服务器,CouchbaseMock 非常有用,因为它是自包含的(没有 需要将其安装到系统中)并允许额外的 仪器。

【讨论】:

以上是关于如何在没有嵌入式服务器或新集群的情况下模拟 couchbase 进行验收测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 AsyncTask 类或新线程进行游标查询? [复制]

如何在没有 Youtube 或 Vimeo 的情况下嵌入视频?

如何在没有循环的情况下进行模拟?

如何在没有评估环境的情况下对函数进行集群导出

如何在没有嵌入式订阅的情况下执行一个又一个异步操作

多次使用相同的模拟对象/数组时,如何在没有引用问题的情况下导入模拟数据以进行测试