-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mock context #34
Mock context #34
Conversation
ec1609a
to
9e2f1f0
Compare
@ArekPiekarz do you want to review this PR? |
Sure, I will have more time tomorrow to do it. |
Ok, I'll wait for you. |
This commit adds Context objects for static methods and free functions. Expectations are still global, but the context object will clean up any global expectations when it drops. This has a few benefits: * Call counts will be verified when the context object drops * The context object can be used to checkpoint its method * "No matching expectation found" errors will no longer poison the static method's global mutex. Panics in the returning method still will, however. Fixes #30
This commit changes Context objects for static methods of generic structs. It removes the method's generic parameters from the Context object, so only the struct's generic parameters (if any) remain. Similarly, Context::expect will now only have the method's generic parameters.
I tested how it works now and I am happy to say it fulfills my suggestions about being hard to misuse. It certainly is safer than the optional context mechanism in Mocktopus. Maybe the Context struct could be marked As for bikeshedding, I see the convention of controlling the mocked functions through ones with a prefix I noticed in some cases the runtime errors could be more descriptive, but I don't know if they are related to this pull request or if a new issue should be created, or if they are fixed on other branch. When a free function is called without a matching expectation we get an error: #![feature(proc_macro_hygiene)]
#![allow(non_snake_case)]
use mockall::automock;
use mockall::predicate::eq;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(test)] {
use mock_SomeModule::freeFunction;
} else {
use SomeModule::freeFunction;
}
}
#[cfg_attr(test, automock)]
#[allow(dead_code)]
mod SomeModule {
pub fn freeFunction(_arg: i32) {}
}
fn myFunc() {
freeFunction(7);
}
#[test]
fn someTest() {
let context = mock_SomeModule::freeFunction_context();
context.expect().with(eq(8)); // not matched
myFunc();
} When there are a few expectations and one is not satisfied, we get a function name, but not which expectation exactly is to blame: #![feature(proc_macro_hygiene)]
#![allow(non_snake_case)]
use mockall::automock;
use mockall::predicate::eq;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(test)] {
use mock_SomeModule::freeFunction;
} else {
use SomeModule::freeFunction;
}
}
#[cfg_attr(test, automock)]
#[allow(dead_code)]
mod SomeModule {
pub fn freeFunction(_arg: i32) {}
}
fn myFunc() {
freeFunction(7);
freeFunction(8);
}
#[test]
fn someTest() {
let context = mock_SomeModule::freeFunction_context();
context.expect().times(1).with(eq(7));
context.expect().times(1).with(eq(7)); // not matched
context.expect().times(1).with(eq(8));
myFunc();
} |
Thanks for your feedback, and happy hacking! |
Add context objects for mocking static methods
This PR adds Context objects for static methods and free functions. Expectations are still global, but the context object will clean up any global expectations when it drops. This has a few benefits:
Fixes #30
CC @ArekPiekarz