CodeSandwich / Mocktopus

Mocking framework for Rust
MIT License
233 stars 20 forks source link

Does mocktopus support mocking on method in different crate? #53

Open kungfucop opened 4 years ago

kungfucop commented 4 years ago

I have 2 creates in my project, base and service, and service crate based on base. And the code is something like this:

crate base {
   db.rs 
   #[mockable]
  fun get_users()
}

crate service {
  import db;
   fun get_users() -> vec<Users>{
     let db_users = db.get_users();
    if db_users.len() > 0 {
      return db_users;
    } else {
      let users = vec!['a', 'b', 'c']
     return users;
   }
 }
 mod test {
    import db:get_users()
   #[test]
    fun test_get_user{
     let results = Vec::new();
     db.get_users.mock_safe( || MockResult::Return(Ok(results)));
      assert_eq(get_users(),  vec!['a', 'b', 'c']);
    }
   }
}

I expect db.get_users() is not called, but mock result returns, but it actually didn't respect the mock and goes to expect the real db.get_users() code. Does mocktopus support mocking on method in different crate or I made mistakes?

Thanks a lot

CodeSandwich commented 4 years ago

It should be possible. If the dependency is built with mocking enabled for the function, it will be available in the depdendee. You probably should add a special feature gate to enable that, the regular #[cfg(test)] items are not enabled when built as a dependency.

ekump commented 4 years ago

I just ran into the same issue with a project I am working on and found this helpful: https://github.com/rust-lang/rust/issues/45599

I changed my Cargo.toml file to make mocktopus an optional dependency under dependencies instead of dev-dependencies and added a "mockable" feature:

[dependencies]
mocktopus = { version = "*", optional = true }

[features]
mockable = ["mocktopus"]

In the dependency library I wished to mock I changed

#[cfg(test)]
use mocktopus::macros::*;

to

#[cfg(any(feature = "mockable", mockable))]
use mocktopus::macros::*;

and

#[cfg_attr(test, mockable)]
pub fn the_function_i_want_to_mock() {
    ...
}

to

#[cfg_attr(feature = "mockable", mockable)]
pub fn the_function_i_want_to_mock() {
    ...
}

and I enable the feature only when running tests with cargo +nightly test --features "mockable"

kungfucop commented 4 years ago

Thank you @ekump for the share, and I worked around in same way!