Skip to content

An example rust library that easily mocks an interface for unit testing with the mockall crate.

Notifications You must be signed in to change notification settings

peterjamesmatthews/rust-mock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust Mock

An example rust library that easily mocks an interface for unit testing with the mockall crate.

An important Application method cool_algorithm needs to be unit tested.

cool_algorithm relies on an external service and for whatever reason, that external service cannot be used during unit testing.

To remedy this, we define the I32Calculator trait:

rust-mock/src/lib.rs

Lines 74 to 83 in 8e6303e

pub trait I32Calculator {
/// Returns the sum of `x` and `y`.
fn add(&self, x: i32, y: i32) -> i32;
/// Returns the difference of `x` and `y`.
fn subtract(&self, x: i32, y: i32) -> i32;
/// Returns the product of `x` and `y`.
fn multiply(&self, x: i32, y: i32) -> i32;
/// Returns the quotient of `x` and `y`.
fn divide(&self, x: i32, y: i32) -> i32;
}

And implement it for external service's client ExternalI32Calculator:

rust-mock/src/lib.rs

Lines 89 to 105 in 8e6303e

impl I32Calculator for ExternalI32Calculator {
fn add(&self, _x: i32, _y: i32) -> i32 {
panic!("Can't call this in unit tests!")
}
fn subtract(&self, _x: i32, _y: i32) -> i32 {
panic!("Can't call this in unit tests!")
}
fn multiply(&self, _x: i32, _y: i32) -> i32 {
panic!("Can't call this in unit tests!")
}
fn divide(&self, _x: i32, _y: i32) -> i32 {
panic!("Can't call this in unit tests!")
}
}

We then declare an i32_calculator field in our Application that is I32Calculator:

rust-mock/src/lib.rs

Lines 109 to 111 in 8e6303e

pub struct Application {
pub i32_calculator: Box<dyn I32Calculator>,
}

To enable mocking of I32Calculator, we add the #[cfg_attr(test, mockall::automock)] attribute to the trait's definition:

rust-mock/src/lib.rs

Lines 73 to 74 in 8e6303e

#[cfg_attr(test, mockall::automock)]
pub trait I32Calculator {

In our unit test, we then create a mock object that is I32Calculator and set up expectations and return values for the methods will be called during the cool_algorithm call:

rust-mock/src/lib.rs

Lines 129 to 174 in 8e6303e

#[cfg(test)]
mod tests {
use super::*;
use mockall::predicate;
#[test]
fn cool_algorithm_does_nothing() {
let number = 100;
// mock object that is I32Calculator
let mut mock_i32_calculator = MockI32Calculator::new();
// set up our expectations
mock_i32_calculator
.expect_add()
.times(1)
.with(predicate::eq(number), predicate::eq(0))
.return_const(number);
mock_i32_calculator
.expect_subtract()
.times(1)
.with(predicate::eq(number), predicate::eq(0))
.return_const(number);
mock_i32_calculator
.expect_multiply()
.times(1)
.with(predicate::eq(number), predicate::eq(1))
.return_const(number);
mock_i32_calculator
.expect_divide()
.times(1)
.with(predicate::eq(number), predicate::eq(1))
.return_const(number);
// create our application with our mock calculator
let app = Application {
i32_calculator: Box::new(mock_i32_calculator),
};
// run our unit test of the cool_algorithm
assert_eq!(app.cool_algorithm(number), number);
}
}

About

An example rust library that easily mocks an interface for unit testing with the mockall crate.

Topics

Resources

Stars

Watchers

Forks

Languages