Mocking object's internal dependencies

⚓ Rust    📅 2025-10-20    👤 surdeus    👁️ 1      

surdeus

Coming from Spring/Java world, I struggle to find a nice way to mock object's dependencies in Rust without adding too much test-related stuff to the API.

So, let's say, I have this code:

struct MyApiClient {
    api_token: String,
    driver: external_api::ExternalApiDriver
}

impl MyApiClient {
    fn new(api_token: &str) -> Self {
        let driver = external_api::ExternalApiDriver::new();

        Self { 
            api_token: api_token.to_owned(),
            driver: driver 
        }
    }

    fn call_external_api(&self) -> Result<String, Error> {
        driver.call_api(&token, "SOME_API_METHOD")
    }
}

During testing, I want to ensure that when calling the MyApiClient.call_external_api() method, the ExternalApiDriver.call_api() was called exactly once, with correct arguments.

Creating a mock for the external_api::ExternalApiDriver struct is easy, but I can't find a slick way to replace its default implementation within MyApiClient.

The external_api::ExternalApiDriver object is not used anywhere else in the program, so providing it through the new() constructor seems unnecessarily verbose.

Another option I can think if is creating a #[cfg(test)]-annotated setter method for the driver field, but to me it also doesn't feel like a clean solution, especially if there will be multiple dependencies.

In Java, stuff like this was handled by mocking libraries using dependency injection magic.

I would like to hear, what is the conventional way to hook on object's side effects in Rust, and, if there is none, what would be an appropriate solution to the problem.

3 posts - 3 participants

Read full topic

🏷️ Rust_feed