4.13.0
Changed
-
Improved error message that is supplied with
ArgumentExceptionthrown whenSetuporVerifyare called on a protected method if the method could not be found with both the name and compatible argument types specified (@thomasfdm, #852). -
mock.Invocations.Clear()now removes traces of previous invocations more thoroughly by additionally resetting all setups to an "unmatched" state. (@stakx, #854) -
Consistent
Callbackdelegate validation regardless of whether or notCallbackis preceded by aReturns: Validation for post-Returnscallback delegates used to be very relaxed, but is now equally strict as in the pre-Returnscase.) (@stakx, #876) -
Subscription to mocked events used to be handled less strictly than subscription to regular CLI events. As with the latter, subscribing to mocked events now also requires all handlers to have the same delegate type. (@stakx, #891)
-
Moq will throw when it detects that an argument matcher will never match anything due to the presence of an implicit conversion operator. (@michelcedric, #897, #898)
-
New algorithm for matching invoked methods against methods specified in setup/verification expressions. (@stakx, #904)
Added
-
Added support for setup and verification of the event handlers through
Setup[Add|Remove]andVerify[Add|Remove|All](@lepijohnny, #825) -
Added support for lambda expressions while creating a mock through
new Mock<SomeType>(() => new SomeType("a", "b"))andrepository.Create<SomeType>(() => new SomeType("a", "b")). This makes the process of mocking a class without a parameterless constructor simpler (compiler syntax checker...). (@frblondin, #884) -
Support for matching generic type arguments:
mock.Setup(m => m.Method<It.IsAnyType>(...)). (@stakx, #908)The standard type matchers are:
It.IsAnyType— matches any typeIt.IsSubtype<T>— matchesTand proper subtypes ofTIt.IsValueType— matches only value types
You can create your own custom type matchers:
[TypeMatcher] class Either<A, B> : ITypeMatcher { public bool Matches(Type type) => type == typeof(A) || type == typeof(B); }
-
In order to support type matchers (see bullet point above), some new overloads have been added to existing methods:
-
setup.Callback(new InvocationAction(invocation => ...)),
setup.Returns(new InvocationFunc(invocation => ...)):The lambda specified in these new overloads will receive an
IInvocationrepresenting the current invocation from which type arguments as well as arguments can be discovered. -
Match.Create<T>((object argument, Type parameterType) => ..., ...),
It.Is<T>((object argument, Type parameterType) => ...):Used to create custom matchers that work with type matchers. When a type matcher is used for
T, theargumentreceived by the custom matchers is untyped (object), and its actual type (or rather the type of the parameter for which the argument was passed) is provided via an additional parameterparameterType. (@stakx, #908)
-
Fixed
-
Moq does not mock explicit interface implementation and
protected virtualcorrectly. (@oddbear, #657) -
Invocations.Clear()does not causeVerifyto fail (@jchessir, #733) -
Regression:
SetupAllPropertiescan no longer set up properties whose names start withItem. (@mattzink, #870; @kaan-kaya, #869) -
Regression:
MockDefaultValueProviderwill no longer attempt to setCallBaseto true for mocks generated for delegates. (@dammejed, #874) -
VerifythrowsTargetInvocationExceptioninstead ofMockExceptionwhen one of the recorded invocations was to an async method that threw. (@Cufeadir, #883) -
Moq does not distinguish between distinct events if they have the same name (@stakx, #893)
-
Regression in 4.12.0:
SetupAllPropertiesremoves indexer setups. (@stakx, #901) -
Parameter types are ignored when matching an invoked generic method against setups. (@stakx, #903)
-
For
[Value]Task<object>,.ReturnsAsync(null)throwsNullReferenceExceptioninstead of producing a completed task with resultnull(@voroninp, #909)