asomers / mockall

A powerful mock object library for Rust
Apache License 2.0
1.5k stars 62 forks source link

Is it possible to mock a trait method that has no return? #592

Closed mgumbley-resilient closed 3 months ago

mgumbley-resilient commented 3 months ago

Hi, thank you for mockall - I'm trying to assert that a method in a trait that has no return type is being called:

#[cfg_addr(test, automock)]
pub trait Thing {
  fn start(&mut self);
}
#[test]
fn thing_starts() {
  let mut thing = MockThing::new();
  thing.expect_start().once();
  let mut sut = ThingUser::new(Box::new(thing)); // takes a Box<dyn Thing>
  sut.start_the_thing(); // will call thing.start()
}

When I run this, I have a panic with:

MockThing::start: Expectation(<anything>) Returning default values requires the "nightly" feature

I'm not using "nightly" - and am not actually returning anything: the function is called for its side-effects.

I can work around this by making the start method return unit (-> ()) and in my test, use thing.expect_start().once().return_const(()); but it's a little messy. Could this case be simplified?

asomers commented 3 months ago

A function that has "no return" really does just return (). And when you write your expectations, you really do need to do .return_const(()). But as the error message says, you can leave that part out if you enable the "nightly" feature. The specific nightly compiler feature that we need is Specialization, and unfortunately that one looks a long way from stabilization.

mgumbley-resilient commented 3 months ago

Thank you Alan.