I am struggling with the problem of how to use the Moq-Setup-Return construct.
First, my setting:
Some repository of type IRepository
-Interface has to implement the StoreAsync
-Method that returns a StoreResult object with the stored entity as property included.
using System.Threading.Tasks;
using Moq;
using Xunit;
namespace Tests
{
public class Entity { }
public class StoreResult
{
public Entity Entity { get; set; }
}
public interface IRepository
{
Task<StoreResult> StoreAsync(Entity entity);
}
public class Tests
{
[Fact]
public void Test()
{
var moq = new Mock<IRepository>();
moq.Setup(m => m.StoreAsync(It.IsAny<Entity>())).Returns(e => Task.FromResult<Task<StoreResult>>(new StoreResult {Entity = e}));
}
}
}
Now I try to write a Mock-Objekt for the IRepository-Interface, but I do not know how to code the Return-Statement so that the StoreResult-Object includes the entity given as a parameter to the StoreAsync-Function.
I read about this topic in Moq ReturnsAsync() with parameters and Returning value that was passed into a method.
I have tried
moq.Setup(m => m.StoreAsync(It.IsAny<Entity>()))
.ReturnsAsync(entity => new StoreResult {Entity = entity});
with the error statement "Cannot convert lambda expression to type "StoreResult
", because it is not a delegate type.
And with the same error message I tried
moq.Setup(m => m.StoreAsync(It.IsAny<Entity>()))
.Returns(e => Task.FromResult<Task<StoreResult>>(new StoreResult {Entity = e}));
I am using a .NET Core xUnit environment with Moq 4.6.36-alpha
Thank you for your help.
The only way to have supported out-by-reference parameters would be if the async feature were done by a low-level CLR rewrite instead of a compiler-rewrite.
Async unit tests that return Task have none of the problems of async unit tests that return void. Async unit tests that return Task enjoy wide support from almost all unit test frameworks.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.
Thanks to the tip from Callum Linigton I came to the following solution:
moq
.Setup(m => m.StoreAsync(It.IsAny<Entity>()))
.Returns((Entity e) => Task.FromResult(new StoreResult {Entity = e}));
The key difference is to specify the type for the input parameter of the lambda expression in order to avoid ambiguous calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With