Skip to content

Commit fc27c36

Browse files
1 parent d15fec4 commit fc27c36

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Test/handler_tests.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/// @module handler_tests
2+
/// @description This file demonstrates how to write unit tests for Mountain's
3+
/// handler logic using the `mockall` crate for dependency mocking.
4+
5+
// This code would live in a file under the `tests/` directory in the Mountain crate.
6+
// It requires `mockall` to be added as a `[dev-dependency]`.
7+
8+
#[cfg(test)]
9+
mod tests {
10+
use std::{path::PathBuf, sync::Arc};
11+
12+
use Common::{
13+
error::CommonError,
14+
fs::{
15+
FsReader,
16+
dto::{FileSystemStatDto, FileTypeDto},
17+
},
18+
};
19+
use async_trait::async_trait;
20+
use mockall::automock;
21+
22+
// --- Mocking the Trait ---
23+
// We create a dummy struct and impl the trait we want to mock.
24+
// The `#[automock]` attribute will generate `MockTestFsReader` for us.
25+
#[automock]
26+
#[async_trait]
27+
pub trait TestFsReader {
28+
async fn ReadFile(&self, Path:&PathBuf) -> Result<Vec<u8>, CommonError>;
29+
}
30+
31+
// --- The Function/Handler Under Test ---
32+
// This is a simplified handler that depends on any type that implements
33+
// `FsReader`. Thanks to generics, we can pass in a real FsReader or our mock
34+
// one.
35+
async fn LogicThatReadsAFile(
36+
Reader:Arc<dyn TestFsReader + Send + Sync>,
37+
Path:PathBuf,
38+
) -> Result<String, CommonError> {
39+
let Bytes = Reader.ReadFile(&Path).await?;
40+
Ok(String::from_utf8(Bytes).unwrap_or_default())
41+
}
42+
43+
// --- The Test Case ---
44+
#[tokio::test]
45+
async fn Test_LogicThatReadsAFile_ReturnsCorrectString_OnSuccess() {
46+
// 1. Arrange: Create the mock object.
47+
let mut MockReader = MockMockTestFsReader::new();
48+
49+
// 2. Arrange: Set up an expectation.
50+
// We expect the `ReadFile` method to be called exactly once.
51+
// When it is, we tell it to return `Ok("hello".to_vec())`.
52+
MockReader
53+
.expect_ReadFile()
54+
.times(1)
55+
.returning(|_path| Ok("hello".as_bytes().to_vec()));
56+
57+
// 3. Act: Call our handler function with the mock dependency.
58+
let result = LogicThatReadsAFile(Arc::new(MockReader), PathBuf::from("/fake/path.txt")).await;
59+
60+
// 4. Assert: Check that the result is what we expect.
61+
assert!(result.is_ok());
62+
assert_eq!(result.unwrap(), "hello");
63+
}
64+
65+
#[tokio::test]
66+
async fn Test_LogicThatReadsAFile_ReturnsError_OnFailure() {
67+
// 1. Arrange: Create the mock object.
68+
let mut MockReader = MockMockTestFsReader::new();
69+
70+
// 2. Arrange: Set up an expectation for failure.
71+
// We tell the mock to return an FsNotFound error when called.
72+
MockReader
73+
.expect_ReadFile()
74+
.times(1)
75+
.returning(|path| Err(CommonError::FsNotFound(path.clone())));
76+
77+
// 3. Act: Call our handler function.
78+
let path = PathBuf::from("/not/found.txt");
79+
let result = LogicThatReadsAFile(Arc::new(MockReader), path.clone()).await;
80+
81+
// 4. Assert: Check that the result is the correct error.
82+
assert!(result.is_err());
83+
match result.unwrap_err() {
84+
CommonError::FsNotFound(p) => assert_eq!(p, path),
85+
_ => panic!("Expected FsNotFound error"),
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)