Mockers
Mocking library for Rust.
Limitations
For now it is not a full-featured mocking library, but just a prototype to gather feedback. For example, only methods with two or less arguments are supported, non-'static lifetimes are not supported and so on.
Mocking magic is implemented using compiler plugin, so nightly Rust is required. It was tested to work with 1.9.0-nightly (924da295c 2016-04-10).
Usage
First of all, you must use nighly Rust:
Add mockers and mockers_macros as dependencies to your Cargo.toml:
[]
= "0.2.1"
[]
= "0.2.1"
Say we have air crate with some trait and method using this trait:
// src/lib.rs
Import mockers crate and mockers_macros compiler plugin into test crate:
// tests/lib.rs
extern crate air;
extern crate mockers;
Now create mock type for some trait:
mock!
Note that you have to duplicate trait definition inside mock!
macro. This is because compiler plugins work at code AST level
and can't get trait information by it's name.
It is all ready now, lets write test:
use Scenario;
Run tests:
$ cargo test
…
running 1 test
test test_make_hotter ... FAILED
failures:
---- test_make_hotter stdout ----
thread 'test_make_hotter' panicked at 'Unexpected call of `get_temperature`, no calls are expected', /Users/kriomant/Dropbox/Projects/mockers/src/lib.rs:254
note: Run with `RUST_BACKTRACE=1` for a backtrace.
failures:
test_make_hotter
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
error test failed
Seems like call to get_temperature was not planned by scenario.
Lets start writing scenario:
Note that we used _call suffix when specifying expected method calls.
Start tests again:
…
---- test_make_hotter stdout ----
thread 'test_make_hotter' panicked at 'called `Result::unwrap()` on an `Err` value: "36 is not equal to 4"', ../src/libcore/result.rs:746
…
Oops, seems we have a bug in set_temperature_20 function. Fix it and test again:
…
running 1 test
test test_make_hotter ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
…
Argument matchers
*_call mock methods receive argument matchers as parameters. Any value
of required type (which implements Eq) can be used as matcher,
in this case it is just compared to actual argument value.
You can use arg! macro to match argument values against pattern:
…
scenario.expect;
Basic matchers (comparison: eq, ne, gt, …; logical: not, or, and)
are available in matchers module.
Specialized matchers (like is_empty or contains) will be available soon.
You may easily create ad-hoc matchers using check method:
use check;
scenario.expect;
Unfortunately, you can't create polymorphic checker this way (i.e. checker
which may be used for Option<T> for any T). You have to write own
struct and MatchArg implementation in order to do that.
Use check! macro instead of check function to get slightly more
informative error message:
extern crate mockers;
scenario.expect;
License
Copyright © 2016 Mikhail Trishchenkov
Distributed under the MIT License.