Greg Dietsche
Greg Dietsche

Reputation: 1060

Moq using ReturnsAsync and modify It.IsAny input parameter

When using ReturnsAsync, we could only get it to return a new object. Is there a better / more correct way to write the code below?

In this example, we have some sort of repository, and our implementation takes in an object of type Thing that has an Id (we want to pretend that our db set the Id) property:

var repo = new Mock<IRepositoryOfThings>();

//Is there a better way to do this perhaps using ReturnsAsync??
repo.Setup(r => r.Add(It.IsAny<Thing>())).Returns(
    (Thing x) =>
    {
        var tcs = new TaskCompletionSource<Thing>();
        x.Id = Guid.NewGuid().ToString();
        tcs.SetResult(x);
        return tcs.Task;
    });

Thanks!

Upvotes: 3

Views: 1300

Answers (2)

tubakaya
tubakaya

Reputation: 497

You can just initialize an instance of Thing and return that instance in your setup.

   var repo = new Mock<IRepositoryOfThings>();
   var thing = new Thing
   {
       Id = Guid.NewGuid().ToString()
   };
   repo.Setup(r => r.Add(It.IsAny<Thing>())).ReturnsAsync(thing);

Upvotes: 0

JustinHui
JustinHui

Reputation: 729

This is the best I could find:

var repo = new Mock<IRepositoryOfThings>();

repo.Setup(r => r.Add(It.IsAny<Thing>())).Returns(
    (Thing x) =>
    {
        x.Id = Guid.NewGuid().ToString();
        return Task.FromResult(x);
    });

It's effectively the same as your answer but only very slightly shorter.

Upvotes: 2

Related Questions