rust / expert
Snippet
Isolieren von Seiteneffekten in Tests mittels Thread-lokalem Mocking
Beim Schreiben von Unit-Tests in Rust laufen diese standardmäßig parallel. Um globale Funktionen oder FFI-Zustände ohne Race-Conditions sicher zu mocken, können wir `thread_local!` verwenden. Dies isoliert Mock-Zustände ausschließlich auf den Thread des jeweiligen Tests.
snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use std::cell::RefCell;thread_local! {static MOCK_DB_RESPONSE: RefCell<Option<Result<String, &'static str>>> = const { RefCell::new(None) };}fn fetch_data_from_db() -> Result<String, &'static str> {MOCK_DB_RESPONSE.with(|mock| {if let Some(ref response) = *mock.borrow() {response.clone()} else {Ok("real_production_data".to_string())}})}#[cfg(test)]mod tests {use super::*;#[test]fn test_database_error_handling() {MOCK_DB_RESPONSE.with(|mock| {*mock.borrow_mut() = Some(Err("Timeout"));});assert_eq!(fetch_data_from_db(), Err("Timeout"));MOCK_DB_RESPONSE.with(|mock| *mock.borrow_mut() = None);}}
Erklärung
1
static MOCK_DB_RESPONSE: RefCell<Option<Result<...>>> = ...
Deklariert eine Thread-lokale statische Variable mit einer RefCell zur Speicherung des Mock-Ergebnisses.
2
MOCK_DB_RESPONSE.with(|mock| {
Greift über einen Scoped-Closure-Mechanismus auf den an den Thread gebundenen Mock-Container zu.
3
*mock.borrow_mut() = Some(Err("Timeout"));
Konfiguriert den Fehlerzustand auf dem aktuellen Test-Thread, ohne andere parallel laufende Tests zu beeinflussen.