nrxus / faux

Struct mocking library for Rust
https://nrxus.github.io/faux/
MIT License
411 stars 14 forks source link

Async in stubbed `async fn` methods #53

Closed silmeth closed 1 year ago

silmeth commented 1 year ago

Is it possible to make stubbed mock’s behaviour async? I have an asynchronous database abstraction object that has async fn methods for executing DB queries. When mocking the object I can stub those methods with results that are ready immediately – but is it possible to stub them with an async block or a custom future?

I would like to be able eg. to add a certain async sleep in those stubs, to force the async runtime to execute another job after starting the call to the mock, or to use async channels from them. Is it possible?

If it’s impossible, I think I can work around this with only blocking code but it would be easier to use async directly in the mocks themselves.

nrxus commented 1 year ago

Hey @silmeth there's currently no way of making the mock itself be async. This is mostly blocked on the fact that there are no async closures in Rust: https://github.com/rust-lang/rust/issues/62290

My 2 cents based on what you describe though is that it sounds like there is a smell in either your tests or your code. You shouldn't be relying on sleeps in mocks to make your tests pass, the channels idea seems pretty good and you should be able to use a blocking channel.

silmeth commented 1 year ago

@nrxus Yes, I used blocking primitives for synchronization in the end. The ability to use async channels would be nice, but I see the problem lack of stable async closures makes.

One way around it would be giving the mock a vec of futures instead of a futures-producer, and it would return those one-by-one when invoked – but it wouldn’t be consistent with how regular methods are mocked, so I see why you wouldn’t implement it like that…

Anyway, thanks for the reply!