-
-
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 = "" });
Moq creates an implementation of the mocked type. If the type is an interface, it creates a class that implements the interface. If the type is a class, it creates an inherited class, and the members of that inherited class call the base class. But in order to do that it has to override the members. If a class has members that can't be overridden (they aren't virtual, abstract) then Moq can't override them to add its own behaviors.
In this case there's no need to mock **PagingOptions **because it's easy to use a real one. Instead of this:
var mockPagingOptions = new Mock<PagingOptions>();
mockPagingOptions.Setup(po => po.Limit).Returns(25);
mockPagingOptions.Setup(po => po.Offset).Returns(0);
Do this:
var pagingOptions = new PagingOptions { Limit = 25, Offset = 0 };
How do we determine whether or not to mock something? Generally speaking, we mock something if we don't want to include the concrete runtime implementation in our test. We want to test one class not both at the same time.
But in this case **PagingOptions **is just a class that holds some data. There's really no point in mocking it. It's just as easy to use the real thing.
From the second unit test you tried, when you create instance of SearchViewModel, there is no initialize of _productionOrderService.
if _productionOrderService is created in SearchViewModel it might not be initialized due to lack of their dependencies.
you have to provide _productionOrderService to the SearchViewModel by
make it public and set it when create SearchViewModel make it private and pass it through constructor when create SearchViewModel then you can mock _productionOrderService and setup GetListAllAsync() in unit test
Unsupported expression: Non-overridable members (here: ) may not be used in setup / verification expressions
The **moq **use dynamic proxy to create wrapper around mocked type in order to be able to intercept calls and change the behaviour of the invoked methods.
How proxy is built?
If you mocking **interface **proxy is just an implementation of the interface If you have **class **the proxy is override of the class Question: Could you mock sealed class or non virtual(abstract) method?
You guess, no. There is no way to create wrapper around it using dynamic proxy. **moq **itself suggesting the same, if you look at the error:
Non-overridable members (here: BlobServiceProvider.GetBlockBlobContainer) may not be used in setup
To answer your question, either you need to extract the interface out of your provider and mock it or mark the method as virtual. Personaly, I do prefer option with the interface but it might requre some refactoring and DI.
Nunit Moq: Unsupported expression: Value Non-overridable members may not be used in setup / verification expressions
I'm unaware of any built-in DataGeneric class, so I assume it is a user-defined class.
The error says
... Value Non-overridable members (here: DataGeneric.get_Value) ...
which means you should not mock the RiskId.Value.
You should try to setup a mock for the RiskId itself:
data.Setup(i => i.RiskId).Returns(new StringData("123")); I've assumed your StringData has a constructor which can receive its value.
Moq is constrained isolation framework. It can mock only virtual methods.
Extract interface from you Login class.
public interface ILogin
{
List<string> GetInfo(string tableName, string[] columnNames);
// other members
}
Add this interface to the class definition.
public class Login : ILogin { public List GetInfo(string tableName, string[] columnNames) { using (var command = new SqlCommand("SELECT * from [" + tableName + "]", connection)) { connection.Open(); using (var reader = command.ExecuteReader()) { List infoList = new List(); while (reader.Read()) { for (int i = 0; i < columnNames.Length; i++) { infoList.Add(reader[columnNames[i]].ToString()); } } return infoList; } } } } Mock this interface instead of class.
var mock = new Mock();
You have to make the property overridable, so make it virtual:
public virtual int? ProductMaxLenght { get ...
C#: Moq : Message: System.NotSupportedException : Unsupported expression: item => item.RouteId Non-overridable members
As RouteIdis not virtual, you cannot mock it. But since ContextData is a simple data class without behaviour, there is also no need to mock it. You can do simply:
ContextArbiter.Setup(p => p.GetContextData()).Returns(new ContextData { RouteId = "64" });