Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq does not contain a definition for ReturnAsync?

I am trying to mock some API calls to a third-party service for unit testing purposes. I really just want this mocked function to return the same RestEase.Response<...> each time.

// Setup
var VeracrossMock = new Mock<IVeracrossAPI>(MockBehavior.Strict);
Func<List<VeracrossStudent>> func = () => new List<VeracrossStudent>() { new VeracrossStudent() { First_name = "Bob", Last_name = "Lob" } };
RestEase.Response<List<VeracrossStudent>> resp = new RestEase.Response<List<VeracrossStudent>>("", new HttpResponseMessage(HttpStatusCode.OK), func);

// Problem is on the line below
VeracrossMock.Setup(api => api.GetStudentsAsync(1, null, CancellationToken.None)).ReturnsAsync<RestEase.Response<List<VeracrossStudent>>>(resp);

It gives me a red underline and then claims the ReturnsAsync doesn't exist, or at least not with the arguments that I've given it.

Error CS1929 'ISetup<IVeracrossAPI, Task<Response<List<VeracrossStudent>>>>' does not contain a definition for 'ReturnsAsync' and the best extension method overload 'SequenceExtensions.ReturnsAsync<Response<List<VeracrossStudent>>>(ISetupSequentialResult<Task<Response<List<VeracrossStudent>>>>, Response<List<VeracrossStudent>>)' requires a receiver of type 'ISetupSequentialResult<Task<Response<List<VeracrossStudent>>>>'

How am I supposed to be using ReturnsAsync? Clueless as to how to mock this.

like image 908
Nils Guillermin Avatar asked Jun 22 '18 14:06

Nils Guillermin


3 Answers

The generic argument being used does not match the arguments of the member being mocked.

Remove the generic argument

VeracrossMock
    .Setup(_ => _.GetStudentsAsync(1, null, CancellationToken.None))
    .ReturnsAsync(resp);

and the method will infer the desired generic arguments based on the member being mocked.

like image 65
Nkosi Avatar answered Oct 17 '22 23:10

Nkosi


Another option for this error is because ReturnsAsync is only available for methods that return a Task<T>. For methods that return only a Task, either of the following options can be used:

mock.Setup(arg=>arg.DoSomethingAsync()).Returns(Task.FromResult(default(object)))


mock.Setup(arg=>arg.DoSomethingAsync()).Returns(Task.CompletedTask);
like image 20
Yonatan Nir Avatar answered Oct 18 '22 00:10

Yonatan Nir


I've hit this error message several times over the past few weeks and keep forgetting how I fixed it, so I'm writing it here in the hope it helps someone. Each time it was because I was being daft and was passing in an object/type when the method I was setting up expected a list of objects/types.

like image 29
zappa Avatar answered Oct 18 '22 00:10

zappa