Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability for asynchronously waiting for an invocation #1457

Open
BalassaMarton opened this issue Jan 16, 2024 · 2 comments
Open

Add ability for asynchronously waiting for an invocation #1457

BalassaMarton opened this issue Jan 16, 2024 · 2 comments

Comments

@BalassaMarton
Copy link

BalassaMarton commented Jan 16, 2024

Some asynchronous code, like the ones involving channels, are hard to test, because writing to a channel starts background tasks on the thread pool that are expected to complete eventually, but are impossible to await. Similar problems arise when using the Rx.NET library, where observables might dispatch their updates asynchronously. Adding delays in tests can increase build times significantly when the project is large. I will use the below testing code as an example:

var subscriber = Mock.Of<IAsyncObserver<string>>();

await topic.SubscribeAsync(subscriber); // topic is the system under test
await topic.PublishAsync("test");

Mock.Get(subscriber).Verify(_ => _.OnNextAsync("test"));

This test will be inherently flaky if the system under test is dispatching messages using a Channel<string> or any other asynchronous mechanism where calling the subscriber is done in a background task. What we would need here is the ability to asynchronously wait for the invocation within some defined timeout:

var subscriber = Mock.Of<IAsyncObserver<string>>();

await topic.SubscribeAsync(subscriber); // topic is the system under test
await topic.PublishAsync("test");

await Mock.Get(subscriber).WaitAsync(_ => _.OnNextAsync("test"), TimeSpan.FromSeconds(10));

This task should only throw if the specified invocation did not happen within the provided timespan.

Alternatively, if Mock.GetMatchingInvocationCount was public, or there was some public matching method on IInvocation itself, we could write our own utilities like the above WaitAsync method.

Back this issue
Back this issue

Copy link

Due to lack of recent activity, this issue has been labeled as 'stale'.
It will be closed if no further activity occurs within 30 more days.
Any new comment will remove the label.

@github-actions github-actions bot added the stale label Aug 24, 2024
@kzu kzu added this to the 5.0.0 milestone Aug 24, 2024
@kzu
Copy link
Member

kzu commented Aug 24, 2024

Hi there. Yes, the lack of a public API for consuming matchers against invocations are a limitation of the current approach. This should be addressed in a future Moq.

@kzu kzu removed this from the 5.0.0 milestone Sep 2, 2024
@github-actions github-actions bot removed the stale label Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants