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
impl TestContext
pub fn new() -> Self
Sourcepub fn set_data<T: Any + Send + Sync>(&mut self, key: &str, value: T)
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}Sourcepub fn get_data<T: Any + Send + Sync>(&self, key: &str) -> Option<&T>
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}Trait Implementations§
Source§impl Clone for TestContext
impl Clone for TestContext
Auto Trait Implementations§
impl Freeze for TestContext
impl !RefUnwindSafe for TestContext
impl Send for TestContext
impl Sync for TestContext
impl Unpin for TestContext
impl !UnwindSafe for TestContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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