You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When testing a function with a mocked implementation passed in, it must be a trait by virtue of the fact that a mocked struct is seen as a different type. This is problematic in the context where you do not wish to make the function generic on that input.
I'm not 100% sure what a good solution will look like, but here is a a rough first draft:
// We want to test this function, but we want to mock foo in different waysfnuses_foo(foo:Foo) -> u32{
foo.do_bar()}#[test]fntest_with_mocked_foo(){// provides a Foo which can be used in the same way as a `MockFoo` generated from `automock` applied to a `Foo` structletmut mocked_foo = mockall::use_mocked!(Foo::default());
mocked_foo.expect_do_bar().returning(|| 42);let expect_42 = uses_foo(mocked_foo);}// this is the current solution:// T is needed in order to be able to test this function with a mocked: Would prefer to just use a Foo instead of genericsfnuses_foo_trait<T:FooTrait>(foo:T) -> u32{
foo.do_bar()}#[mockall::automock]traitFooTrait{fndo_bar(&self) -> u32;}#[test]fntest_with_mocked_foo(){// provides a Foo which can be used in the same way as a `MockFoo` generated from `automock` applied to a `Foo` structletmut mocked_foo = MockFooTrait::new();
mocked_foo.expect_do_bar().returning(|| 42);let expect_42 = uses_foo_trait(mocked_foo);}// How this might be made to work:
mockall::struct_mock! {structFoo{
bar:Bar,// if Foo is being mocked:// - adds this field// - redefines the structs implementation to always use `self.mock_foo` instead of `self`
#[mockall::struct_internal]
mock_foo:MockFoo,}// Generatios MockFoo similar to `mockall::automock`, and also redefines implementations to use `self.mock_foo`
#[mockall::automock_struct_internal]// could use `mockall::mock_struct_internal!` insteadimplFoo{fn do_bar(&self) -> u32{self.bar.do_bar()}}// hypothetically would expand to something like....implFoo{fn do_bar(&self) -> u32{self.mocked_self.do_bar()}// and the expansions equivilent to `mockall::automock`fn expect_do_bar(...){self.mocked_self.expect_do_bar(...)}}}
The text was updated successfully, but these errors were encountered:
This is not how Rust works. You cannot create a "Foo" that can be used in the same way as a "MockFoo". Rust is a strongly typed, statically typed language. A variable is either a Foo or a MockFoo, not both. The solution to your problem is to use #[mockall_double] correctly. Or, if for some reason you can't, then you must straighten out all of your cfg directives to ensure that you never pass a MockFoo to a function expecting a Foo or vice versa.
Related issue: #331
Related discussion: #478
When testing a function with a mocked implementation passed in, it must be a trait by virtue of the fact that a mocked struct is seen as a different type. This is problematic in the context where you do not wish to make the function generic on that input.
I'm not 100% sure what a good solution will look like, but here is a a rough first draft:
The text was updated successfully, but these errors were encountered: