TestContext

Struct TestContext 

Source
pub struct TestContext {
    pub docker_handle: Option<DockerHandle>,
    pub start_time: Instant,
    pub data: HashMap<String, Box<dyn Any + Send + Sync>>,
}

Fields§

§docker_handle: Option<DockerHandle>§start_time: Instant§data: HashMap<String, Box<dyn Any + Send + Sync>>

Implementations§

Source§

impl TestContext

Source

pub fn new() -> Self

Source

pub fn set_data<T: Any + Send + Sync>(&mut self, key: &str, value: T)

Store arbitrary data in the test context

Examples found in repository?
examples/mongodb_integration.rs (line 99)
68fn main() {
69    println!("🐳 MongoDB Integration Example with Container Hooks");
70    println!("==================================================");
71    println!();
72    
73    // Define container configuration
74    let mongo_container = ContainerConfig::new("mongo:5.0")
75        .port(27017, 27017)
76        .env("MONGO_INITDB_ROOT_USERNAME", "admin")
77        .env("MONGO_INITDB_ROOT_PASSWORD", "password")
78        .name("test_mongodb")
79        .ready_timeout(Duration::from_secs(30));
80    
81    println!("📋 Container Configuration:");
82    println!("  Image: {}", mongo_container.image);
83    println!("  Ports: {:?}", mongo_container.ports);
84    println!("  Environment: {:?}", mongo_container.env);
85    println!("  Name: {:?}", mongo_container.name);
86    println!("  Ready Timeout: {:?}", mongo_container.ready_timeout);
87    println!();
88    
89    // Clone for before_each hook
90    let mongo_container_before = mongo_container.clone();
91    
92    // Register before_each hook to start container
93    before_each(move |ctx| {
94        println!("🔄 before_each: Starting MongoDB container...");
95        
96        // Start the container
97        let container_id = mongo_container_before.start()
98            .map_err(|e| format!("Failed to start container: {}", e))?;
99        ctx.set_data("mongo_container_id", container_id.clone());
100        
101        println!("✅ before_each: MongoDB container {} started", container_id);
102        Ok(())
103    });
104    
105    // Register after_each hook to stop container
106    let mongo_container_after = mongo_container.clone();
107    rust_test_harness::after_each(move |ctx| {
108        println!("🔄 after_each: Stopping MongoDB container...");
109        
110        // Get container ID from context
111        let container_id = ctx.get_data::<String>("mongo_container_id")
112            .expect("Container ID should be available");
113        
114        // Stop the container
115        mongo_container_after.stop(&container_id)
116            .map_err(|e| format!("Failed to stop container: {}", e))?;
117        
118        println!("✅ after_each: MongoDB container {} stopped", container_id);
119        Ok(())
120    });
121    
122    // Test 1: Basic MongoDB operations
123    test("test_mongodb_basic_operations", |ctx| {
124        println!("🧪 Running test: test_mongodb_basic_operations");
125        
126        // Get container ID from context
127        let container_id = ctx.get_data::<String>("mongo_container_id")
128            .expect("Container ID should be available")
129            .to_string();
130        
131        // Create MongoDB client
132        let mut client = MongoClient::new(container_id);
133        
134        // Connect to MongoDB
135        client.connect()?;
136        
137        // Insert a document
138        client.insert_document("users", r#"{"name": "John Doe", "email": "john@example.com"}"#)?;
139        
140        // Find documents
141        let documents = client.find_documents("users", r#"{"name": "John Doe"}"#)?;
142        assert_eq!(documents.len(), 2);
143        
144        // Disconnect
145        client.disconnect()?;
146        
147        println!("✅ test_mongodb_basic_operations passed");
148        Ok(())
149    });
150    
151    // Test 2: Multiple operations
152    test("test_mongodb_multiple_operations", |ctx| {
153        println!("🧪 Running test: test_mongodb_multiple_operations");
154        
155        // Get container ID from context
156        let container_id = ctx.get_data::<String>("mongo_container_id")
157            .expect("Container ID should be available")
158            .to_string();
159        
160        // Create MongoDB client
161        let mut client = MongoClient::new(container_id);
162        
163        // Connect to MongoDB
164        client.connect()?;
165        
166        // Insert multiple documents
167        client.insert_document("products", r#"{"name": "Laptop", "price": 999.99}"#)?;
168        client.insert_document("products", r#"{"name": "Mouse", "price": 29.99}"#)?;
169        client.insert_document("products", r#"{"name": "Keyboard", "price": 79.99}"#)?;
170        
171        // Find documents
172        let documents = client.find_documents("products", r#"{"price": {"$gt": 50}}"#)?;
173        assert_eq!(documents.len(), 2); // Laptop and Keyboard
174        
175        // Disconnect
176        client.disconnect()?;
177        
178        println!("✅ test_mongodb_multiple_operations passed");
179        Ok(())
180    });
181    
182    // Test 3: Error handling
183    test("test_mongodb_error_handling", |ctx| {
184        println!("🧪 Running test: test_mongodb_error_handling");
185        
186        // Get container ID from context
187        let container_id = ctx.get_data::<String>("mongo_container_id")
188            .expect("Container ID should be available")
189            .to_string();
190        
191        // Create MongoDB client
192        let client = MongoClient::new(container_id);
193        
194        // Try to insert without connecting (should fail)
195        let result = client.insert_document("users", r#"{"name": "Test"}"#);
196        assert!(result.is_err());
197        assert_eq!(result.unwrap_err(), "Not connected to MongoDB");
198        
199        println!("✅ test_mongodb_error_handling passed");
200        Ok(())
201    });
202    
203    // Test 4: Performance testing
204    test("test_mongodb_performance", |ctx| {
205        println!("🧪 Running test: test_mongodb_performance");
206        
207        // Get container ID from context
208        let container_id = ctx.get_data::<String>("mongo_container_id")
209            .expect("Container ID should be available")
210            .to_string();
211        
212        // Create MongoDB client
213        let mut client = MongoClient::new(container_id);
214        
215        // Connect to MongoDB
216        client.connect()?;
217        
218        // Simulate bulk operations
219        for i in 0..100 {
220            client.insert_document("bulk_data", &format!(r#"{{"index": {}, "data": "bulk_item_{}"}}"#, i, i))?;
221        }
222        
223        // Simulate bulk retrieval
224        let documents = client.find_documents("bulk_data", r#"{"index": {"$lt": 50}}"#)?;
225        assert_eq!(documents.len(), 2); // Mock always returns 2
226        
227        // Disconnect
228        client.disconnect()?;
229        
230        println!("✅ test_mongodb_performance passed");
231        Ok(())
232    });
233    
234    println!("\n🚀 Running MongoDB integration tests...");
235    println!("   Each test will get a fresh MongoDB container via before_each");
236    println!("   Each test will clean up its container via after_each");
237    println!();
238    
239    // Run tests with container hooks enabled
240    let config = TestConfig {
241        skip_hooks: Some(false),
242        ..Default::default()
243    };
244    
245    let result = run_tests_with_config(config);
246    
247    println!("\n📊 Test Results:");
248    if result == 0 {
249        println!("✅ All MongoDB integration tests passed!");
250        println!("🎯 Container lifecycle management working correctly");
251        println!("🐳 Each test got its own MongoDB container");
252        println!("🧹 Each test cleaned up its container properly");
253    } else {
254        println!("❌ Some tests failed");
255    }
256    
257    println!("\n💡 Key Benefits of this approach:");
258    println!("   • Clean separation of concerns");
259    println!("   • Each test gets a fresh container");
260    println!("   • Automatic cleanup via after_each");
261    println!("   • Easy to configure containers");
262    println!("   • No complex global state management");
263}
Source

pub fn get_data<T: Any + Send + Sync>(&self, key: &str) -> Option<&T>

Retrieve data from the test context

Examples found in repository?
examples/mongodb_integration.rs (line 111)
68fn main() {
69    println!("🐳 MongoDB Integration Example with Container Hooks");
70    println!("==================================================");
71    println!();
72    
73    // Define container configuration
74    let mongo_container = ContainerConfig::new("mongo:5.0")
75        .port(27017, 27017)
76        .env("MONGO_INITDB_ROOT_USERNAME", "admin")
77        .env("MONGO_INITDB_ROOT_PASSWORD", "password")
78        .name("test_mongodb")
79        .ready_timeout(Duration::from_secs(30));
80    
81    println!("📋 Container Configuration:");
82    println!("  Image: {}", mongo_container.image);
83    println!("  Ports: {:?}", mongo_container.ports);
84    println!("  Environment: {:?}", mongo_container.env);
85    println!("  Name: {:?}", mongo_container.name);
86    println!("  Ready Timeout: {:?}", mongo_container.ready_timeout);
87    println!();
88    
89    // Clone for before_each hook
90    let mongo_container_before = mongo_container.clone();
91    
92    // Register before_each hook to start container
93    before_each(move |ctx| {
94        println!("🔄 before_each: Starting MongoDB container...");
95        
96        // Start the container
97        let container_id = mongo_container_before.start()
98            .map_err(|e| format!("Failed to start container: {}", e))?;
99        ctx.set_data("mongo_container_id", container_id.clone());
100        
101        println!("✅ before_each: MongoDB container {} started", container_id);
102        Ok(())
103    });
104    
105    // Register after_each hook to stop container
106    let mongo_container_after = mongo_container.clone();
107    rust_test_harness::after_each(move |ctx| {
108        println!("🔄 after_each: Stopping MongoDB container...");
109        
110        // Get container ID from context
111        let container_id = ctx.get_data::<String>("mongo_container_id")
112            .expect("Container ID should be available");
113        
114        // Stop the container
115        mongo_container_after.stop(&container_id)
116            .map_err(|e| format!("Failed to stop container: {}", e))?;
117        
118        println!("✅ after_each: MongoDB container {} stopped", container_id);
119        Ok(())
120    });
121    
122    // Test 1: Basic MongoDB operations
123    test("test_mongodb_basic_operations", |ctx| {
124        println!("🧪 Running test: test_mongodb_basic_operations");
125        
126        // Get container ID from context
127        let container_id = ctx.get_data::<String>("mongo_container_id")
128            .expect("Container ID should be available")
129            .to_string();
130        
131        // Create MongoDB client
132        let mut client = MongoClient::new(container_id);
133        
134        // Connect to MongoDB
135        client.connect()?;
136        
137        // Insert a document
138        client.insert_document("users", r#"{"name": "John Doe", "email": "john@example.com"}"#)?;
139        
140        // Find documents
141        let documents = client.find_documents("users", r#"{"name": "John Doe"}"#)?;
142        assert_eq!(documents.len(), 2);
143        
144        // Disconnect
145        client.disconnect()?;
146        
147        println!("✅ test_mongodb_basic_operations passed");
148        Ok(())
149    });
150    
151    // Test 2: Multiple operations
152    test("test_mongodb_multiple_operations", |ctx| {
153        println!("🧪 Running test: test_mongodb_multiple_operations");
154        
155        // Get container ID from context
156        let container_id = ctx.get_data::<String>("mongo_container_id")
157            .expect("Container ID should be available")
158            .to_string();
159        
160        // Create MongoDB client
161        let mut client = MongoClient::new(container_id);
162        
163        // Connect to MongoDB
164        client.connect()?;
165        
166        // Insert multiple documents
167        client.insert_document("products", r#"{"name": "Laptop", "price": 999.99}"#)?;
168        client.insert_document("products", r#"{"name": "Mouse", "price": 29.99}"#)?;
169        client.insert_document("products", r#"{"name": "Keyboard", "price": 79.99}"#)?;
170        
171        // Find documents
172        let documents = client.find_documents("products", r#"{"price": {"$gt": 50}}"#)?;
173        assert_eq!(documents.len(), 2); // Laptop and Keyboard
174        
175        // Disconnect
176        client.disconnect()?;
177        
178        println!("✅ test_mongodb_multiple_operations passed");
179        Ok(())
180    });
181    
182    // Test 3: Error handling
183    test("test_mongodb_error_handling", |ctx| {
184        println!("🧪 Running test: test_mongodb_error_handling");
185        
186        // Get container ID from context
187        let container_id = ctx.get_data::<String>("mongo_container_id")
188            .expect("Container ID should be available")
189            .to_string();
190        
191        // Create MongoDB client
192        let client = MongoClient::new(container_id);
193        
194        // Try to insert without connecting (should fail)
195        let result = client.insert_document("users", r#"{"name": "Test"}"#);
196        assert!(result.is_err());
197        assert_eq!(result.unwrap_err(), "Not connected to MongoDB");
198        
199        println!("✅ test_mongodb_error_handling passed");
200        Ok(())
201    });
202    
203    // Test 4: Performance testing
204    test("test_mongodb_performance", |ctx| {
205        println!("🧪 Running test: test_mongodb_performance");
206        
207        // Get container ID from context
208        let container_id = ctx.get_data::<String>("mongo_container_id")
209            .expect("Container ID should be available")
210            .to_string();
211        
212        // Create MongoDB client
213        let mut client = MongoClient::new(container_id);
214        
215        // Connect to MongoDB
216        client.connect()?;
217        
218        // Simulate bulk operations
219        for i in 0..100 {
220            client.insert_document("bulk_data", &format!(r#"{{"index": {}, "data": "bulk_item_{}"}}"#, i, i))?;
221        }
222        
223        // Simulate bulk retrieval
224        let documents = client.find_documents("bulk_data", r#"{"index": {"$lt": 50}}"#)?;
225        assert_eq!(documents.len(), 2); // Mock always returns 2
226        
227        // Disconnect
228        client.disconnect()?;
229        
230        println!("✅ test_mongodb_performance passed");
231        Ok(())
232    });
233    
234    println!("\n🚀 Running MongoDB integration tests...");
235    println!("   Each test will get a fresh MongoDB container via before_each");
236    println!("   Each test will clean up its container via after_each");
237    println!();
238    
239    // Run tests with container hooks enabled
240    let config = TestConfig {
241        skip_hooks: Some(false),
242        ..Default::default()
243    };
244    
245    let result = run_tests_with_config(config);
246    
247    println!("\n📊 Test Results:");
248    if result == 0 {
249        println!("✅ All MongoDB integration tests passed!");
250        println!("🎯 Container lifecycle management working correctly");
251        println!("🐳 Each test got its own MongoDB container");
252        println!("🧹 Each test cleaned up its container properly");
253    } else {
254        println!("❌ Some tests failed");
255    }
256    
257    println!("\n💡 Key Benefits of this approach:");
258    println!("   • Clean separation of concerns");
259    println!("   • Each test gets a fresh container");
260    println!("   • Automatic cleanup via after_each");
261    println!("   • Easy to configure containers");
262    println!("   • No complex global state management");
263}
Source

pub fn has_data(&self, key: &str) -> bool

Check if data exists in the test context

Source

pub fn remove_data<T: Any + Send + Sync>(&mut self, key: &str) -> Option<T>

Remove data from the test context

Trait Implementations§

Source§

impl Clone for TestContext

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TestContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.