### Mocking Modules and Foreign Functions Source: https://context7.com/asomers/mockall/llms.txt Use `#[double]` from `mockall_double` to switch between real and mock implementations of modules. This example shows how to mock the `http` module within the `network` module. ```rust use mockall::* use mockall_double::double; mod network { #[cfg(test)] use mockall::automock; #[cfg_attr(test, automock)] pub mod http { pub fn get(url: &str) -> Result { // Real implementation unimplemented!() } pub fn post(url: &str, body: &str) -> Result { unimplemented!() } } } #[double] use network::http; fn fetch_data(endpoint: &str) -> Result { http::get(endpoint) } #[cfg(test)] mod tests { use super::*; use mockall::predicate::*; #[test] fn test_module_mock() { let ctx = http::get_context(); ctx.expect() .with(eq("https://api.example.com/data")) .returning(|_| Ok("{\"status\": \"ok\"}".to_string())); let result = fetch_data("https://api.example.com/data"); assert_eq!(Ok("{\"status\": \"ok\"}".to_string()), result); } } ``` -------------------------------- ### Basic Mock Object Usage in Rust Source: https://github.com/asomers/mockall/blob/master/README.md This example demonstrates how to define a trait, automatically derive a mock object for it using `automock`, and then use the mock object within a unit test to define expected behavior and assert outcomes. ```rust #[cfg(test)] use mockall::{automock, mock, predicate::*}; #[cfg_attr(test, automock)] trait MyTrait { fn foo(&self, x: u32) -> u32; } #[cfg(test)] mod tests { use super::*; #[test] fn mytest() { let mut mock = MockMyTrait::new(); mock.expect_foo() .with(eq(4)) .times(1) .returning(|x| x + 1); assert_eq!(5, mock.foo(4)); } } ``` -------------------------------- ### Non-Send Types with _st Variants Source: https://context7.com/asomers/mockall/llms.txt For non-`Send` return types or arguments, use the `_st` (single-threaded) variants: `return_const_st`, `returning_st`, `return_once_st`, and `withf_st`. This example uses `withf_st` and `returning_st` with `Rc`. ```rust use mockall::*; use std::rc::Rc; #[automock] trait LocalCache { fn get(&self, key: Rc) -> Rc; } #[test] fn test_non_send_types() { let mut mock = MockLocalCache::new(); let expected_key = Rc::new("mykey".to_string()); let key_clone = expected_key.clone(); mock.expect_get() .withf_st(move |k| *k == key_clone) .returning_st(|_| Rc::new("value".to_string())); let result = mock.get(expected_key); assert_eq!(*result, "value"); } ``` -------------------------------- ### Unit Test with Mockall Source: https://github.com/asomers/mockall/blob/master/mockall/README.md This Rust unit test demonstrates how to create a mock object, define expectations for its methods, and assert its behavior. The `expect_foo` method sets up the mock for the `foo` function, specifying the input, number of calls, and the return value. ```rust #[cfg(test)] mod tests { use super::*; #[test] fn mytest() { let mut mock = MockMyTrait::new(); mock.expect_foo() .with(eq(4)) .times(1) .returning(|x| x + 1); assert_eq!(5, mock.foo(4)); } } ``` -------------------------------- ### Mocking Reference Return Values Source: https://context7.com/asomers/mockall/llms.txt Demonstrates how to mock methods that return references. Use `return_const` for `&self` methods and `return_var` or `returning` for `&mut self` methods. For string slices, `return_const` automatically uses an owned `String` internally. ```rust use mockall::*; struct Item { name: String, value: i32, } #[automock] trait Cache { fn get(&self, key: &str) -> &Item; fn get_mut(&mut self, key: &str) -> &mut Item; fn name(&self) -> &str; } #[test] fn test_reference_returns() { let mut mock = MockCache::new(); // Return reference to stored value mock.expect_get() .return_const(Item { name: "test".to_string(), value: 42 }); // Return mutable reference mock.expect_get_mut() .return_var(Item { name: "mutable".to_string(), value: 0 }); // String slice - automatically uses owned String internally mock.expect_name() .return_const("cached_name".to_owned()); assert_eq!(42, mock.get("key").value); mock.get_mut("key").value = 100; assert_eq!("cached_name", mock.name()); } ``` -------------------------------- ### Add mockall_double Dependency Source: https://github.com/asomers/mockall/blob/master/mockall_double/README.md Add mockall_double as a full dependency and mockall as a dev-dependency in your Cargo.toml file. ```toml [dependencies] mockall_double = "0.3.1" [dev-dependencies] mockall = "0.12.0" ``` -------------------------------- ### Add Mockall to Cargo.toml for Development Dependencies Source: https://github.com/asomers/mockall/blob/master/mockall/README.md To use Mockall in your unit tests, add it to the `[dev-dependencies]` section of your `Cargo.toml` file. This ensures Mockall is only compiled and available during testing. ```toml [dev-dependencies] mockall = "0.14.0" ``` -------------------------------- ### Argument Matching with Predicates in Mockall Source: https://context7.com/asomers/mockall/llms.txt Use the `with` method with predicates or `withf` for custom matching functions to verify arguments passed to mock methods. Arguments are passed by reference to matchers. ```rust use mockall::* use mockall::predicate::* #[automock] trait FileSystem { fn open(&self, path: &str) -> Option; fn write(&self, fd: u32, data: &[u8]) -> usize; } #[test] fn test_argument_matching() { let mut mock = MockFileSystem::new(); // Match specific string value mock.expect_open() .with(eq("/etc/passwd")) .returning(|_| Some(3)); // Custom predicate with withf mock.expect_write() .withf(|fd, data| *fd == 3 && data.len() > 0) .returning(|_, data| data.len()); // Fallback for any other path mock.expect_open() .return_const(None); assert_eq!(Some(3), mock.open("/etc/passwd")); assert_eq!(None, mock.open("/nonexistent")); assert_eq!(5, mock.write(3, b"hello")); } ``` -------------------------------- ### Setting Return Values in Mockall Source: https://context7.com/asomers/mockall/llms.txt Mockall offers `return_const` for constant values, `returning` for closures that compute values from arguments, and `return_once` for non-Clone types or one-time computations. ```rust use mockall::* struct NonClone(u32); #[automock] trait Foo { fn constant(&self) -> u32; fn computed(&self, x: u32, y: u32) -> u32; fn once(&self) -> NonClone; } #[test] fn test_return_values() { let mut mock = MockFoo::new(); // Return a constant value (Clone types) mock.expect_constant() .return_const(42u32); // Compute return value from arguments mock.expect_computed() .returning(|x, y| x + y); // Return non-Clone value once mock.expect_once() .return_once(|| NonClone(99)); assert_eq!(42, mock.constant()); assert_eq!(7, mock.computed(3, 4)); assert_eq!(99, mock.once().0); } ``` -------------------------------- ### Mock Structs with mock! Macro Source: https://context7.com/asomers/mockall/llms.txt The `mock!` macro allows mocking structs with multiple impl blocks or external traits. Define the struct name and list methods/trait implementations without bodies. ```rust use mockall::mock; // External trait we don't control trait Serializable { fn serialize(&self) -> Vec; } mock! { pub DataStore { fn get(&self, key: &str) -> Option; fn set(&mut self, key: &str, value: &str); } impl Serializable for DataStore { fn serialize(&self) -> Vec; } impl Clone for DataStore { fn clone(&self) -> Self; } } #[test] fn test_mock_struct() { let mut mock = MockDataStore::new(); mock.expect_get() .with(mockall::predicate::eq("user")) .returning(|_| Some("Alice".to_string())); mock.expect_set() .return_const(()); mock.expect_serialize() .returning(|| vec![1, 2, 3]); assert_eq!(Some("Alice".to_string()), mock.get("user")); mock.set("key", "value"); assert_eq!(vec![1, 2, 3], mock.serialize()); } ``` -------------------------------- ### Basic Trait Mocking with #[automock] Source: https://context7.com/asomers/mockall/llms.txt Use `#[automock]` to automatically generate a mock struct for a trait. The mock struct will have an `expect_*` method for each trait method to set expectations. ```rust use mockall::* use mockall::predicate::* #[automock] trait MyTrait { fn foo(&self, x: u32) -> u32; } fn call_with_four(x: &dyn MyTrait) -> u32 { x.foo(4) } #[test] fn test_basic_mock() { let mut mock = MockMyTrait::new(); mock.expect_foo() .with(predicate::eq(4)) .times(1) .returning(|x| x + 1); assert_eq!(5, call_with_four(&mock)); } ``` -------------------------------- ### Mock Static Methods with Context Objects Source: https://context7.com/asomers/mockall/llms.txt Static methods use Context objects instead of mock instances. The context manages expectations and must be held for the duration of the test. Use synchronization (Mutex) when testing static methods across multiple tests. ```rust use mockall::automock; use std::sync::Mutex; #[automock] trait Factory { fn create(id: u32) -> Self; fn instance_count() -> usize; } static MTX: Mutex<()> = Mutex::new(()); #[test] fn test_static_methods() { let _lock = MTX.lock().unwrap(); // Get context for static method let ctx = MockFactory::create_context(); ctx.expect() .with(mockall::predicate::eq(42)) .returning(|_| MockFactory::default()); let count_ctx = MockFactory::instance_count_context(); count_ctx.expect() .returning(|| 5); let _mock = MockFactory::create(42); assert_eq!(5, MockFactory::instance_count()); } ``` -------------------------------- ### Mock Generic Methods with Static Parameters Source: https://context7.com/asomers/mockall/llms.txt Generic methods with `'static` parameters are mocked by specifying the type via turbofish syntax. Each generic instantiation operates independently. ```rust use mockall::automock; #[automock] trait Converter { fn convert(&self, value: T) -> String; } #[test] fn test_generic_methods() { let mut mock = MockConverter::new(); // Set expectation for i32 type mock.expect_convert::() .returning(|v| format!("int: {}", v)); // Set different expectation for String type mock.expect_convert::() .returning(|v| format!("string: {}", v)); assert_eq!("int: 42", mock.convert(42i32)); assert_eq!("string: hello", mock.convert("hello".to_string())); } ``` -------------------------------- ### Async Traits Support Source: https://context7.com/asomers/mockall/llms.txt Mockall supports native async traits (Rust 1.75+), `async_trait`, and `trait_variant`. The `#[automock]` attribute must appear before the async crate's attribute. ```rust use mockall::*; use async_trait::async_trait; #[automock] #[async_trait] trait AsyncDatabase { async fn fetch(&self, id: u32) -> Option; async fn store(&self, id: u32, data: &str) -> bool; } #[tokio::test] async fn test_async_trait() { let mut mock = MockAsyncDatabase::new(); mock.expect_fetch() .with(mockall::predicate::eq(1)) .returning(|_| Some("record_1".to_string())); mock.expect_store() .returning(|_, _| true); assert_eq!(Some("record_1".to_string()), mock.fetch(1).await); assert!(mock.store(2, "new_data").await); } ``` -------------------------------- ### Basic mockall_double Usage Source: https://github.com/asomers/mockall/blob/master/mockall_double/README.md Use the `#[double]` attribute to easily create a mock version of a struct. This requires `#[cfg(test)]` for mockall's automock. ```rust use mockall_double::double; mod mockable { #[cfg(test)] use mockall::automock; pub struct Foo {} #[cfg_attr(test, automock)] impl Foo { pub fn foo(&self, x: u32) -> u32 { // ... 0 } } } #[double] use mockable::Foo; fn bar(f: Foo) -> u32 { f.foo(42) } #[cfg(test)] mod tests { use super::*; #[test] fn bar_test() { let mut mock = Foo::new(); mock.expect_foo() .returning(|x| x + 1); assert_eq!(43, bar(mock)); } } ``` -------------------------------- ### Mocking Generic Methods with Non-'static Parameters Source: https://context7.com/asomers/mockall/llms.txt Use the `#[mockall::concretize]` attribute on generic methods with non-'static parameters. When mocking these methods, use `withf` instead of `with` to provide a closure for argument matching. ```rust use mockall::; use std::path::Path; #[automock] trait FileOperations { #[mockall::concretize] fn read>(&self, path: P) -> Vec; #[mockall::concretize] fn exists>(&self, path: P) -> bool; } #[test] fn test_concretize() { let mut mock = MockFileOperations::new(); // Use withf instead of with for concretized methods mock.expect_read() .withf(|p| p.as_ref() == Path::new("/etc/hosts")) .returning(|_| b"127.0.0.1 localhost".to_vec()); mock.expect_exists() .withf(|p| p.as_ref().starts_with("/tmp")) .return_const(true); let content = mock.read("/etc/hosts"); assert!(!content.is_empty()); assert!(mock.exists("/tmp/test.txt")); } ``` -------------------------------- ### Call Count Verification in Mockall Source: https://context7.com/asomers/mockall/llms.txt Verify method call counts using the `times` method, which accepts exact numbers, ranges, or `never()`. Call counts are checked when the mock object is dropped. ```rust use mockall::* #[automock] trait Counter { fn increment(&self); fn decrement(&self); fn reset(&self); } #[test] fn test_call_counts() { let mut mock = MockCounter::new(); // Must be called exactly 3 times mock.expect_increment() .times(3) .return_const(()); // Must be called 1 to 5 times (inclusive) mock.expect_decrement() .times(1..=5) .return_const(()); // Must never be called mock.expect_reset() .never() .return_const(()); mock.increment(); mock.increment(); mock.increment(); mock.decrement(); mock.decrement(); // mock.reset() would panic - never() constraint } ``` -------------------------------- ### Enforce Method Call Order with Sequence Source: https://context7.com/asomers/mockall/llms.txt Use the `Sequence` struct to enforce a specific order of method calls across multiple mock objects. Expectations are added to a sequence using `in_sequence`. ```rust use mockall::Sequence; use mockall::automock; #[automock] trait Connection { fn connect(&self); fn send(&self, data: &str); fn disconnect(&self); } #[test] fn test_sequence() { let mut seq = Sequence::new(); let mut mock = MockConnection::new(); mock.expect_connect() .times(1) .in_sequence(&mut seq) .return_const(()); mock.expect_send() .times(1) .in_sequence(&mut seq) .return_const(()); mock.expect_disconnect() .times(1) .in_sequence(&mut seq) .return_const(()); // Must be called in this exact order mock.connect(); mock.send("hello"); mock.disconnect(); // Calling out of order would panic } ``` -------------------------------- ### Checkpoints for Mid-Test Validation Source: https://context7.com/asomers/mockall/llms.txt The `checkpoint` method validates all current expectations, panics if call counts are not satisfied, and then clears them for new expectations. This is useful for multi-phase tests. ```rust use mockall::*; #[automock] trait Logger { fn log(&self, msg: &str); } #[test] fn test_checkpoints() { let mut mock = MockLogger::new(); // First phase expectations mock.expect_log() .times(2) .return_const(()); mock.log("start"); mock.log("processing"); // Validate first phase, clear expectations mock.checkpoint(); // Second phase expectations mock.expect_log() .times(1) .return_const(()); mock.log("done"); // Expectations verified when mock is dropped } ``` -------------------------------- ### Mock Generic Traits and Associated Types Source: https://context7.com/asomers/mockall/llms.txt Generic traits become generic mock structs. Associated types require specifying concrete types in the `#[automock]` attribute. ```rust use mockall::automock; #[automock(type Item = u32; type Error = String;)] trait Iterator2 { type Item; type Error; fn next(&mut self) -> Result, Self::Error>; } #[automock] trait Container { fn add(&mut self, item: T); fn get(&self, index: usize) -> Option<&T>; } #[test] fn test_generic_traits() { // Mock with associated types let mut iter_mock = MockIterator2::new(); iter_mock.expect_next() .times(3) .returning(|| Ok(Some(42))); iter_mock.expect_next() .returning(|| Ok(None)); assert_eq!(Ok(Some(42)), iter_mock.next()); // Mock generic trait with specific type parameter let mut container: MockContainer = MockContainer::new(); container.expect_add() .return_const(()); container.add("hello".to_string()); } ``` -------------------------------- ### Define a Trait for Mocking with Mockall Source: https://github.com/asomers/mockall/blob/master/mockall/README.md This Rust code defines a trait `MyTrait` and uses the `#[automock]` attribute to automatically generate a mock implementation. This is typically done in the test module. ```rust #[cfg(test)] use mockall::{automock, mock, predicate::*}; #[cfg_attr(test, automock)] trait MyTrait { fn foo(&self, x: u32) -> u32; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.