-
-
Notifications
You must be signed in to change notification settings - Fork 114
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Problem
Integration tests frequently need to poll an async operation until it reaches an expected state. Currently this requires manual polling loops:
OrderResponse? order = null;
var deadline = DateTime.UtcNow.AddSeconds(25);
while (DateTime.UtcNow < deadline)
{
order = await Customer.Client.GetFromJsonAsync<OrderResponse>($"/api/orders/{_orderId}");
if (order?.Status == OrderStatus.Fulfilled) break;
await Task.Delay(500);
}
await Assert.That(order!.Status).IsEqualTo(OrderStatus.Fulfilled);This pattern appeared 3 times in a single example project (order workflow, resilience tests, event verification). It's verbose, error-prone (forgetting null checks, incorrect deadline logic), and obscures the test intent.
Proposed API
// Poll an async lambda until the assertion passes
await Assert.That(async () =>
{
var order = await Client.GetFromJsonAsync<OrderResponse>($"/api/orders/{id}");
return order!.Status;
}).Eventually().IsEqualTo(OrderStatus.Fulfilled)
.Within(TimeSpan.FromSeconds(25))
.WithInterval(TimeSpan.FromMilliseconds(500));
// Simpler variant for boolean conditions
await Assert.That(async () =>
{
var response = await Client.GetAsync($"/api/orders/{id}");
var order = await response.Content.ReadFromJsonAsync<OrderResponse>();
return order?.Status == OrderStatus.Fulfilled;
}).Eventually().IsTrue()
.Within(TimeSpan.FromSeconds(25));Suggested defaults
Within()- required (no implicit infinite timeout)WithInterval()- default 500ms
Use Cases
- Waiting for background workers to process messages
- Eventually-consistent reads after writes
- Waiting for external service state changes
- Health check readiness polling
- Any async operation that needs time to complete
Context
Discovered while building the CloudShop Aspire + TUnit example (#4761). This was the single biggest source of boilerplate in integration tests.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request