Mocking an interface ISomething
with method Task<List<int>> GetIdsAsync(int)
I can do the following to use the parameter in generating the return:
mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
.ReturnsAsync((int n) => new List<int>(n));
I can also mock the method throwing an exception:
mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
.ThrowsAsync(new InvalidOperationException());
But I would actually like to throw new InvalidOperationException($"{n} is not valid");
using the input parameter to generate the error message in the exception.
I cannot figure out what the syntax would be for this, assuming of course that it is possible?
I tried:
mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
.ThrowsAsync((int n) => new InvalidOperationException($"{n} is not valid"));
Which seemed reasonable but gives a somewhat complex error
CS1929 'ISetup<ISomething, Task<List<int>>>' does not contain a
definition for 'ThrowsAsync' and the best extension method overload
'SequenceExtensions.ThrowsAsync(ISetupSequentialResult<Task>,
Exception)' requires a receiver of type 'ISetupSequentialResult<Task>'
CodePudding user response:
As of this answer, there is currently no ThrowsAsync
that takes a value function similar to ReturnsAsync
. All take Exception
as the argument.
A work around would be to create a local variable, capture the input parameter in a callback and use that in the throw.
//...
int n = 0;
mock
.Setup(_ => _.GetIdsAsync(It.IsAny<int>()))
.Callback((int arg) => n = arg)
.ThrowsAsync(new InvalidOperationException($"{n} is not valid"));
//...