用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/gar-ai/mallorn --skill rust-mocking命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | rust-mocking |
| description | Create mocks using mockall and trait-based abstractions. Use when unit testing code with external dependencies. |
Trait-based mocking with mockall for isolated unit tests.
# Cargo.toml
[dev-dependencies]
mockall = "0.12"
use mockall::{automock, predicate::*};
#[automock]
trait Repository {
fn get(&self, id: i32) -> Option<User>;
fn save(&self, user: &User) -> Result<(), Error>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_with_mock() {
let mut mock = MockRepository::new();
// Setup expectations
mock.expect_get()
.with(eq(123))
.times(1)
.returning(|_| Some(User::default()));
// Use mock
let result = service_function(&mock, 123);
assert!(result.is_ok());
}
}
use mockall::{automock, predicate::*};
#[automock]
#[async_trait::async_trait]
trait AsyncRepository {
async fn get(&self, id: i32) -> Result<User, Error>;
async fn save(&self, user: &User) -> Result<(), Error>;
}
#[tokio::test]
async fn test_async_mock() {
let mut mock = MockAsyncRepository::new();
mock.expect_get()
.with(eq(42))
.returning(|_| Ok(User::default()));
let result = mock.get(42).await;
assert!(result.is_ok());
}
use mockall::predicate::*;
mock.expect_process()
.with(eq(42)) // Exact match
.returning(|_| Ok(()));
mock.expect_process()
.with(ne(0)) // Not equal
.returning(|_| Ok(()));
mock.expect_process()
.with(gt(10)) // Greater than
.returning(|_| Ok(()));
mock.expect_search()
.with(str::starts_with("test")) // String predicate
.returning(|_| vec![]);
mock.expect_validate()
.with(function(|x: &User| x.is_valid())) // Custom predicate
.returning(|_| true);
mock.expect_any()
.withf(|a, b| a > b) // Multi-argument predicate
.returning(|_, _| true);
// Return constant
mock.expect_get()
.returning(|_| Some(User::default()));
// Return based on input
mock.expect_get()
.returning(|id| Some(User { id, ..Default::default() }));
// Return once, then different value
mock.expect_get()
.times(1)
.returning(|_| Some(User::new("first")));
mock.expect_get()
.returning(|_| Some(User::new("subsequent")));
// Return error
mock.expect_save()
.returning(|_| Err(Error::NotFound));
// Exact count
mock.expect_get()
.times(3)
.returning(|_| None);
// Range
mock.expect_get()
.times(1..=5)
.returning(|_| None);
// At least
mock.expect_get()
.times(1..)
.returning(|_| None);
// Any number (including zero)
mock.expect_get()
.times(..)
.returning(|_| None);
// Never called
mock.expect_get()
.never();
use mockall::Sequence;
let mut seq = Sequence::new();
mock.expect_connect()
.times(1)
.in_sequence(&mut seq)
.returning(|| Ok(()));
mock.expect_send()
.times(1)
.in_sequence(&mut seq)
.returning(|_| Ok(()));
mock.expect_disconnect()
.times(1)
.in_sequence(&mut seq)
.returning(|| Ok(()));
// Define trait for external dependency
pub trait Storage {
fn read(&self, key: &str) -> Result<Vec<u8>, Error>;
fn write(&self, key: &str, data: &[u8]) -> Result<(), Error>;
}
// Production implementation
pub struct S3Storage {
bucket: String,
}
impl Storage for S3Storage {
fn read(&self, key: &str) -> Result<Vec<u8>, Error> {
// Real S3 operations
}
fn write(&self, key: &str, data: &[u8]) -> Result<(), Error> {
// Real S3 operations
}
}
// Business logic uses trait
pub struct Processor<S: Storage> {
storage: S,
}
impl<S: Storage> Processor<S> {
pub fn process(&, key: &) <(), Error> {
= .storage.(key)?;
.storage.(&(, key), &result)
}
}
tests {
super::*;
mockall::automock;
{ ... }
() {
= MockStorage::();
mock.()
.(())
.(|_| ([, , ]));
mock.()
.((), ())
.(|_, _| (()));
= Processor { storage: mock };
(processor.().());
}
}
#[automock]
trait Cache<K, V> {
fn get(&self, key: &K) -> Option<V>;
fn set(&self, key: K, value: V);
}
#[test]
fn test_generic_mock() {
let mut mock = MockCache::<String, i32>::new();
mock.expect_get()
.with(eq("key".to_string()))
.returning(|_| Some(42));
assert_eq!(mock.get(&"key".to_string()), Some(42));
}
use mockall_double::double;
mod real_module {
pub fn helper() -> i32 { 42 }
}
#[double]
use real_module;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_with_mocked_helper() {
let ctx = real_module::helper_context();
ctx.expect().returning(|| 100);
assert_eq!(real_module::helper(), 100);
}
}
#[automock] for automatic mock generationtimes()See hercules-local-algo/src/db/repo.rs for trait-based repository pattern.
Manage Git worktrees for parallel feature development. Use when the user wants to work on multiple branches simultaneously, create worktrees, switch between features, open terminals/editors for worktrees, or manage parallel development workflows.
Unified linting scripts for all services in the monorepo. Use when the user wants to lint code, check formatting, or run type checks.
Build mithril-cache for torch.compile caching. Use when implementing content-addressable storage, cache keys, eviction, or framework hooks.
基于 SOC 职业分类