devlooped/moq · error · ArgumentNullException
ArgumentNullException: Value cannot be null. (Parameter…
Error message
ArgumentNullException: Value cannot be null. (Parameter 'random')
What it means
This ReturnsAsync overload for Task<TResult> with randomized min/max delay requires a non-null Random instance because it generates a random delay via GetDelay(minDelay, maxDelay, random). Passing null throws ArgumentNullException with parameter name 'random' immediately at setup time.
Solutions
- Pass a Random instance, e.g. new Random(12345) for a reproducible seeded generator
- If no randomness is wanted, use the ReturnsAsync(value, delay) overload with a fixed TimeSpan instead
Example fix
// before mock.Setup(m => m.GetAsync()).ReturnsAsync(result, TimeSpan.Zero, TimeSpan.FromSeconds(1), null); // after mock.Setup(m => m.GetAsync()).ReturnsAsync(result, TimeSpan.Zero, TimeSpan.FromSeconds(1), new Random(42));
Defensive patterns
Strategy: validation
Validate before calling
if (random is null) throw new ArgumentException("ReturnsAsync with min/max delay requires a Random instance"); Type guard
bool HasRandom(Random? r) => r is not null;
Try / catch
try { mock.Setup(m => m.GetAsync()).ReturnsAsync(v, min, max, random); } catch (ArgumentNullException ex) when (ex.ParamName == "random") { /* pass a Random or fixed delay */ } Prevention
- Always pass a seeded Random for deterministic tests
- Prefer fixed-delay overloads when randomness is not needed
- Null-check optional collaborators before building the setup
When it happens
Trigger: mock.Setup(x => x.GetDataAsync()).ReturnsAsync(value, minDelay, maxDelay, null) — the four-argument overload with a null Random.
Common situations: Refactoring from the no-arg ReturnsAsync(value) overload to the delayed overload and passing null 'just to get defaults'; test data builders supplying a null Random.
Related errors
- Value cannot be null. (Parameter 'value')
- Value cannot be null. (Parameter 'value')
- Value cannot be null. (Parameter 'newExpression')
- Delays have to be greater than zero to ensure an async…
- callback (Argument is null)
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/43372ec07c15e006.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/ReturnsExtensions.cs:195
/// Allows to specify the delayed return value of an asynchronous method.
/// </summary>
public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult>(this IReturns<TMock, ValueTask<TResult>> mock,
TResult value, TimeSpan minDelay, TimeSpan maxDelay) where TMock : class
{
var delay = GetDelay(minDelay, maxDelay, Random);
return DelayedResult(mock, value, delay);
}
/// <summary>
/// <para>Allows to specify the delayed return value of an asynchronous method.</para>
/// <para>Use the <see cref="Random"/> argument to pass in (seeded) random generators used across your unit test.</para>
/// </summary>
public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult>(this IReturns<TMock, Task<TResult>> mock,
TResult value, TimeSpan minDelay, TimeSpan maxDelay, Random random) where TMock : class
{
if (random == null)
throw new ArgumentNullException(nameof(random));
var delay = GetDelay(minDelay, maxDelay, random);
return DelayedResult(mock, value, delay);
}
/// <summary>
/// <para>Allows to specify the delayed return value of an asynchronous method.</para>
/// <para>Use the <see cref="Random"/> argument to pass in (seeded) random generators used across your unit test.</para>
/// </summary>
public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult>(this IReturns<TMock, ValueTask<TResult>> mock,
TResult value, TimeSpan minDelay, TimeSpan maxDelay, Random random) where TMock : class
{
if (random == null)
throw new ArgumentNullException(nameof(random));
var delay = GetDelay(minDelay, maxDelay, random);
View on GitHub (pinned to 89a5be629c)