rust / expert
Snippet
Mocking von Abhängigkeiten mit Thread-Lokalem Zustand
Das Mocken von Abhängigkeiten in multithreaded Test-Runnern kann zu Race Conditions führen, wenn ein globaler Zustand verwendet wird. Durch die Nutzung von thread-lokalem Speicher (thread_local!) können Sie Mock-Verhalten sicher injizieren, das nur den aktuellen Testthread betrifft, was eine sichere parallele Ausführung von Unit-Tests ohne externe Testabhängigkeiten ermöglicht.
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
29
30
31
32
33
34
35
36
37
38
39
use std::cell::RefCell;thread_local! {static MOCK_DB_RESPONSE: RefCell<Option<Result<String, &'static str>>> = const { RefCell::new(None) };}pub fn fetch_user_data(user_id: u32) -> Result<String, &'static str> {let mut mock_result = None;MOCK_DB_RESPONSE.with(|cell| {if let Some(ref res) = *cell.borrow() {mock_result = Some(res.clone());}});if let Some(result) = mock_result {result} else {Ok(format!("Real User Data for {}", user_id))}}#[cfg(test)]mod tests {use super::*;#[test]fn test_fetch_user_data_mocked() {MOCK_DB_RESPONSE.with(|cell| {*cell.borrow_mut() = Some(Err("Database Timeout"));});let result = fetch_user_data(42);assert_eq!(result, Err("Database Timeout"));MOCK_DB_RESPONSE.with(|cell| {*cell.borrow_mut() = None;});}}
Erklärung
1
thread_local! {
Deklariert eine thread-lokale statische Variable, die für jeden ausführenden Thread isoliert ist.
2
MOCK_DB_RESPONSE.with(|cell| {
Greift auf die thread-lokale RefCell zu, indem ein Closure an die mit()-Methode übergeben wird.
3
assert_eq!(result, Err("Database Timeout"));
Verifiziert, dass die Funktion den simulierten Fehler dynamisch abgefangen hat, anstatt die echte Logik auszuführen.