testing-patterns-rust
Testing Couchbase Rust applications — unit testing with mockall, integration testing with testcontainers-rs, scope/collection isolation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Testing Couchbase Rust applications — unit testing with mockall, integration testing with testcontainers-rs, scope/collection isolation
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Couchbase SDK error handling — UnambiguousTimeoutException vs AmbiguousTimeoutException, DocumentNotFoundException, CasMismatchException, DurabilityImpossibleException, SDK debug logging, sdk-doctor connectivity diagnostics, retryable vs non-retryable errors, circuit breaker, error best practices
Couchbase SDK patterns for Rust — CAS optimistic locking, retry on CasMismatch, tokio bulk operations with join_all/FuturesUnordered, atomic counters, sub-document (MutateInSpec/LookupInSpec), array operations, exists, replica reads, touch/getAndTouch, preserve_expiry, error handling
Configure and optimize Couchbase SDK connections in Rust — async/tokio cluster setup, singleton pattern, wait_until_ready, timeouts, KV CRUD (upsert/insert/get/replace/remove), expiry, durability, sub-document operations
SQL++ queries with the Couchbase Rust SDK — scope.query, cluster.query, positional and named parameters, scan consistency, deserializing rows into structs, DML (INSERT/UPDATE/DELETE/UPSERT), MutationState RYOW
Distributed ACID transactions are not supported by the Couchbase Rust SDK 1.x — alternatives and workarounds
Entry point for all Couchbase questions — routes to the right skill based on topic and language. Use for any question about Couchbase SDK connection, querying, search, transactions, analytics, field-level encryption, testing, mobile, caching, eventing, Kafka, XDCR, backup, security, or data modeling.
| name | testing-patterns-rust |
| summary | Testing Couchbase Rust applications — unit testing with mockall, integration testing with testcontainers-rs, scope/collection isolation |
| description | Testing Couchbase Rust applications — unit testing with mockall, integration testing with testcontainers-rs, scope/collection isolation |
| compatibility | Rust SDK 1.x. tokio-test + mockall + testcontainers. |
| metadata | {"last_verified":"2026-05","min_server_version":"7.0","handoff":[{"condition":"user asks about testing concepts or strategy","skill":"testing-patterns"},{"condition":"user asks about connection setup or SDK configuration","skill":"server-connection-rust"}]} |
The Rust SDK does not expose trait-based interfaces for mocking. Wrap SDK types behind your own trait and mock that with mockall.
# Cargo.toml
[dev-dependencies]
mockall = "0.12"
tokio-test = "0.4"
use mockall::automock;
#[automock]
pub trait UserStore {
async fn get_user(&self, id: &str) -> Result<User, Box<dyn std::error::Error>>;
}
#[tokio::test]
async fn test_get_user() {
let mut mock = MockUserStore::new();
mock.expect_get_user()
.with(mockall::predicate::eq("user::alice"))
.returning(|_| Ok(User { name: "Alice".into() }));
let result = mock.get_user("user::alice").await.unwrap();
assert_eq!(result.name, "Alice");
}
See shared mock examples for the full pattern reference.
[dev-dependencies]
testcontainers = "0.20"
testcontainers-modules = { version = "0.5", features = ["couchbase"] }
use testcontainers::runners::AsyncRunner;
use testcontainers_modules::couchbase::Couchbase;
use couchbase::authenticator::{Authenticator, PasswordAuthenticator};
use couchbase::cluster::Cluster;
use couchbase::options::cluster_options::ClusterOptions;
#[tokio::test]
async fn integration_upsert_get() {
let node = Couchbase::default().start().await.unwrap();
let port = node.get_host_port_ipv4(11210).await.unwrap();
let cluster = Cluster::connect(
&format!("couchbase://127.0.0.1:{port}"),
ClusterOptions::new(Authenticator::PasswordAuthenticator(
PasswordAuthenticator::new("Administrator", "password"),
)),
).unwrap();
let bucket = cluster.bucket("default");
let collection = bucket.default_collection();
collection.upsert("order::1", serde_json::json!({"status": "pending"}), None)
.await.unwrap();
let result = collection.get("order::1", None).await.unwrap();
let doc: serde_json::Value = result.content_as().unwrap();
assert_eq!(doc["status"], "pending");
}
use uuid::Uuid;
use couchbase::bucket::Bucket;
async fn create_test_scope(bucket: &Bucket) -> String {
let scope_name = format!("test_{}", &Uuid::new_v4().to_string()[..8]);
let mgr = bucket.collections();
mgr.create_scope(&scope_name, None).await.unwrap();
mgr.create_collection(scope_name.clone(), "orders", None, None)
.await.unwrap();
scope_name
}
async fn drop_test_scope(bucket: &Bucket, scope_name: &str) {
bucket.collections().drop_scope(scope_name, None).await.unwrap();
}
| Error | Likely cause in tests | Fix |
|---|---|---|
DocumentNotFound | Key not seeded before test | Seed data before assertions |
BucketNotFound | Test bucket not created | Use default bucket or create in setup |
ServerTimeout | Container not ready | Add tokio::time::sleep after container start |
AuthenticationFailure | Wrong test credentials | Verify username/password match container config |