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 · 0 comments
Open

Add ability for asynchronously waiting for an invocation #1457

BalassaMarton opened this issue Jan 16, 2024 · 0 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.

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

1 participant