vendredi 4 décembre 2020

Mocking Third-Party Functions and Structs in Rust [duplicate]

Requirement:

Need to sensibly test source code business logic without executing third-party code and excessively refactoring legible code to be testable.

Public scope shouldn't need to be altered to support testing either.

For example, test a struct method that calls a standard library function which has been mocked.

Nice-to-Have:

Utilize mockall library to build test mocks.

Example

use std::io::{self, Write};

pub trait Authorable {
    fn write(&self, content: &str);
}

struct Scribe<'a> {
    author: &'a str,
}

impl<'a> Authorable for Scribe<'a> {
    fn write(&self, content: &str) {
        // begin business logic
        let mut record = String::from(content);
        let signature = format!("\n\nAuthor: {}", self.author);
        record.push_str(signature.as_str());
        // end business logic

        // begin third-party usage
        io::stdout().write_all(record.as_bytes()).unwrap();
        io::stdout().flush().unwrap();
        // end third-party usage
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn scribe_write_with_authorable_adds_signature() {
        // fixme - assertions that record, in fn write, is bytes with signature appended
        // fixme - mock third-party stdout write_all and flush to assert expectations
    }
}

Note

Dependency injection was considered.

This example isn't tragic if stdout is utilized but consider other scenarios where source code business logic should be testable without a full integration with third-party code such as a database connection.

This isn't intended as a replacement to heavy integration testing in a robust environment.

Aucun commentaire:

Enregistrer un commentaire