Maybe I'm doing it wrong but there doesn't seem to be a way to use the "Linq to Mocks" syntax for mocking async methods. Is it possible? If not, what would it take to make it possible?
No idea if I read you question right but:
[Test]
public async Task AsyncTest()
{
var mock = new Mock<IFuu>();
var propertyChanged = Mock.Of<INotifyPropertyChanged>();
mock.Setup(x => x.GetAsync()).ReturnsAsync(propertyChanged);
var actual = await mock.Object.GetAsync();
Assert.AreSame(propertyChanged, actual);
}
public interface IFuu
{
Task<INotifyPropertyChanged> GetAsync();
}
Right, but with synchronous methods you can wrap everything up in Mock.Of<T>() and avoid new Mock<T>(), mock.Setup().Returns(), and mock.Object. Like so:
``` c#
[Test]
public void Test()
{
var mock= Mock.Of
var actual = mock.Get();
Assert.AreSame(propertyChanged, actual);
}
public interface IFuu
{
INotifyPropertyChanged Get();
}
```
Mock.Of<T>() can accept a func() as a parameter, but not an async one.
This worked for me:
var mock = Mock.Of<IService>(service => service.DoAsync() == Task.CompletedTask);
I suppose if you replace Task.CompletedTask with Task.FromResult(something) you can do it with just about everything.
I haven't thought much about this, but my gut feeling is that Mock.Of and async might not fit well together. If it were possible, it would be nice if we could do this:
Mock.Of<IFoo>(async foo => await foo.GetAsync() == 42)
Unfortunately, today's C# compiler cannot convert async lambdas to expression trees, so that's a major showstopper.
What we're left with is the ability to work directly with Task objects, like @DaveVdE mentioned above. For example:
Mock.Of<IFoo>(foo => foo.GetAsync() == Task.FromResult(42))
The gains here are pretty small. IMHO it is probably better to accept the fact that LINQ to Mocks will likely never be as feature-complete / powerful as the older fluent API (new Mock<>().Setup().Returns()) due to syntactical constraints. By all means, use Mock.Of<> for what it's good at (setting up a bunch of property and return values in an object graph), but do also use the fluent API for more involved scenarios.
Closing this for now, since there's nothing really that can be done. There's simply no way with today's .NET compilers to transform an async lambda to an expression tree.
Most helpful comment
Closing this for now, since there's nothing really that can be done. There's simply no way with today's .NET compilers to transform an async lambda to an expression tree.