Closed jbuckmccready closed 9 months ago
There isn't a built-in way to do partial mocks in faux
. I've always found them to be an anti-pattern and I think this article explains it better than I could: https://github.com/testdouble/contributing-tests/wiki/Partial-Mock
That being said, I know that sometimes the are necessary evils when dealing with legacy code (meaning adding tests to code that is not tested and thus not factored in a testable way) so I played around a bit and saw that it is doable just a little awkward (but I think the awkwardness here is good because partial mocks are not encouraged and hence should not be easy to use IMO).
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn partial() {
// Make a mock instance
let mut mock = Foo::faux();
// Make a real instance
let real = Foo::new(2, 3);
// mock the function you want to be mocked
faux::when!(mock.to_be_mocked()).then_return(999);
// defer to the real instance for the other function.
// `then()` requires the closure to be static so we need to `move` real
// We could use `then_unchecked()` for more complex cases
faux::when!(mock.to_be_real()).then(move |_| real.to_be_real());
assert_eq!(mock.to_be_mocked(), 999);
assert_eq!(mock.to_be_real(), 3);
}
}
This approach means that you have to manually specify every method that wants to defer to the real method which may be verbose depending on your situation but again I want to emphasize that partial mocks are generally an anti-pattern and a smell that there is something that needs to be improved in the code and tests so I'd recommend not using partial mocks.
For the full code of this example: https://github.com/nrxus/faux-playground/blob/2086fa5cc266f9b9f0de5d43e72fa2c56600c4a4/src/partial_mocks.rs.
Makes sense, thanks for the example.
I don't currently have a use case for this, I am investigating possible limitations I may stumble into in the future.
I poked around a little bit but couldn't find a way to partially mock a struct. E.g., struct with 2 methods
method1
andmethod2
, I want to mockmethod1
and use the real implementation formethod2
, is there a way to do that?