Each SmartWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting
Install-Package SmartWait
dotnet add package SmartWait
WaitFor.Condition(waitCondition, timeoutMessage);
WaitFor.Condition(waitCondition, builder=>builder
.SetMaxWaitTime(maxWaitTime)
.SetCallbackForSuccessful(callback)
.SetNotIgnoredExceptionType(notIgnoredExceptionType)
.Build(), timeoutMessage);
static async Task<bool> Expected()
{
await Task.Delay(TimeSpan.FromSeconds(1));
return true;
}
await WaitFor.Condition(Expected, DefaultTimeOutMessage, timeLimit);
In case when some exceptions happen and we got not expected value we can read information about a number of exceptions and where it happened
In case when you use WaitFor.For
this function wait until the specified condition is met and return the value that we expected.
To do this, you must specify the actions in case of failure using the method OnFailure
var result = WaitFor.For(() => 0)
.Become(a => a == 5)
.OnFailure(_ => 1, fail => fail is NotExpectedValue<int>)
.OnFailure(_ => -2);
//asynchronous option
var result = WaitFor.ForAsync(async () =>
{
await Task.Delay(10);
return 0;
})
.Become(a => a == 5)
.OnFailure(_ => 1, fail => fail is NotExpectedValue<int>)
.OnFailure(_ => -2);
Using the OnSuccess
method, you can specify actions on the value in case of a successful result
var res = WaitFor.For(() => actual).Become(a => a == 3)
.OnSuccess(x => $"New result {x}")
.OnFailureThrowException();
// "New result 3"
- get not expected value
- returns
NotExpectedValue<T>
type.
- returns
- due to some exceptions
- returns
ExceptionsHappened
type.
- returns
We have methods that can help to handle these cases:
WhenNotExpectedValue
andDoWhenNotExpectedValue
WhenWasExceptions
andDoWhenWasExceptions
var res = WaitFor.For(() => 3)
.Become(a => a == 4)
.WhenNotExpectedValue(x => x.ActuallyValue)
.OnFailure(_ => 0);
Console.WriteLine(res) //3
WaitFor.For(() => 3)
.Become(a => a == 4)
.DoWhenNotExpectedValue(x => Console.WriteLine(x))
.OnFailure(_ => 0);
// Console output :
// Timeout after 30.6826992 second(s) and NUMBER OF ATTEMPTS 17
// Expected: (a) => a == 4, but parameter 'a': 3
var testClass = new SomeClass
{
SomeNumber = 3,
Child = new OtherClass
{
SomeNumber = 5
}
};
_ = WaitFor.For(() => testClass)
.Become(a => a.Child.SomeNumber == 1 && a.SomeNumber == 3)
.DoWhenNotExpectedValue(x => Console.WriteLine(x));
/* Console output :
Timeout after 30.6749663 second(s) and NUMBER OF ATTEMPTS 17
Expected: (a) => a.Child.SomeNumber(5) == 1 && a.SomeNumber(3) == 3
*/
If you use OnFailureThrowException
, exception will be throw with next message
await WaitFor.ForAsync(Expected)
.Become(a => a.Child.SomeNumber == 1 && a.SomeNumber == 3)
.OnFailureThrowException();
You can use the predefined algorithm like LogarithmStep and ParabolaStep which calculate delay steps
var res = WaitFor.For(() => actual,
w => w.SetLogarithmStep(Time.FromSeconds).Build())
.Become(a => a == 3)
.OnFailureThrowException();
var res = WaitFor.For(() => actual,
b => b.SetTimeBetweenStep(retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
.Build())
.Become(a => a == 5);