Open U007D opened 6 years ago
Thanks for pointing this out!
Unfortunately, Rust's hygenic macros prevent us from being able to mock traits/methods which use the Self
type, since the compiler can't deduce the meaning Self
when it's used in a macro. I'll properly document that limitation and create a GitHub issue to track research into resolving it.
As for the second compiler error, I don't have an immediate explanation/solution. I will look into this tomorrow evening (UTC) and update this issue with whatever I find.
Thanks for the reply, @DonaldWhyte!
The Self
issue seems to be something I can work around simply by supplying the type explicitly as I have done above.
For the lifetime issue, the compiler doesn't know that the lifetime of the reference being returned is tied to that of the (implied) &self
argument, and because that argument is implied, there doesn't seem to be a way to explain this relationship to the compiler. (The practice of returning &Self
is common when creating fluent API's.)
Hopefully some kind of workaround will spring to mind for the lifetimes issue! Fingers crossed... :)
Hi, @DonaldWhyte. Checking in to see if there is any news before I try crafting a home-grown workaround?
Hey @U007D! I haven't forgotten about this. I've been spending most of the time I have available on double on implementing a concise/expressive call pattern matching API (inspired by Google Mock's).
That'll land into master and be deployed within the next couple of days, so I can begin to look at this again.
Recapping the two issues, we have:
Self
in traits you wish to mockUnfortunately, I think solving (1) is out of reach at the time of writing. I believe Rust's hygenic macros are not sophisticated enough for this. There's a probably a hacky workaround that half solves the problem, but I think solving (2) is a higher priority.
(2) is a big problem. Currently, any functions that return references cannot be mocked. My proposal for this is for the generated mock (there's one Mock
object per trait method) to be aware that it returns a reference. Mock
already owns the values it's configured to return. It can simply return a borrowed reference to the configured return value it owns.
There are some subtleties and corner cases to handle. These are the cases where Mock
s return values are constructed by functions or closures. The value is not known in advance and is thus, not owned by the Mock
. This can be handled though. I'll spec out a prototype PR sometime in the next 1-3 weeks.
Thank you for the update, @DonaldWhyte! Yes, those are the two main issues.
I do hope the Self
issue is solvable, but I agree with you in that not being able to return refs is probably the better one to solve first.
I look forward to the PR once you have it ready! Thanks again for the update.
+1 on this.. also curious about supporting mocking for traits with associated types (https://doc.rust-lang.org/book/second-edition/ch19-03-advanced-traits.html)
Given the following trait:
I have tried:
but this yields:
I tried:
which helps, but I am still left with:
How can I make a mock of
Chal
usingdouble
?