-
-
Notifications
You must be signed in to change notification settings - Fork 800
While using Moq you might run into some questions, we try to answer the most asked of them here.
This is caused by the problem described in dotnet/standard#481, and adding the following to your .csproj file should resolve your issue:
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
The problem indeed gets triggered by System.Threading.Tasks.Extensions package (which Moq references because of ValueTask). Note that it does not target the full .NET Framework, only .NET Standard. Referencing a .NET Standard assembly from a .NET Framework project used to not work, but support for doing just that was added in .NET 4.6.1. Unfortunately, it's a pretty flaky feature. See the linked issue for details.
We are looking into this, but if you run into this issue you could use this solution to circumvent the issue. For more information see miq/moq4#566
Mocking anonymous types can be done through generic helper methods. Since the type is not known before after compilation, generic setup helper methods can be used instead.
public interface IFoo
{
T ReturnSomething<T>();
void CallSomething<T>(T item);
}
- Setting an anonymous return value:
var mock = new Mock<IFoo>();
//Need to extract type <T> for anonymous setup:
void SetupReturnSomething<T>(T anonymous)
{
mock.Setup(foo => foo.ReturnSomething<T>()).Returns(anonymous);
}
SetupReturnSomething(new { Foo = "foo" });
SetupReturnSomething(new { Bar = "bar" });
//Use helper method to pick the right generic type since there is no parameter on method.
T ReturnSomething<T>(T anonymous)
{
mock.Object.ReturnSomething<T>();
}
//Parameter is used only for picking the right generic type.
Assert.Equal("foo", ReturnSomething(new { Foo = "" }).Foo);
Assert.Equal("bar", ReturnSomething(new { Bar = "" }).Bar);
- Setting an anonymous parameter:
var mock = new Mock<IFoo>();
//Parameter is used only for picking the right generic type for setup.
void SetupCallSomething<T>(T anonymous)
{
mock.Setup(foo => foo.CallSomething<T>(It.IsAny<T>()));
}
SetupCallSomething(new { Foo = "" });
SetupCallSomething(new { Bar = "" });
mock.Object.CallSomething(new { Foo = "foo" });
mock.Object.CallSomething(new { Bar = "bar" });
//Need to extract type <T> for anonymous verification:
void VerifyCallSomething<T>(T anonymous)
{
mock.Verify(foo => foo.CallSomething<T>(It.IsAny<T>()), Times.Once);
}
VerifyCallSomething(new { Foo = "" });
VerifyCallSomething(new { Bar = "" });