Moq Changelog

What's new in Moq 4.20.70

Dec 3, 2023
  • Other:
  • Restore GDPR compliance and privacy by @DanWillman in #1402
  • Improve performance for mocking interfaces: Cache GetInterfaceMap by @rauhs in #1351
  • Manually update CHANGELOG.md for now by @kzu in #1407
  • A minor negation in GetDelay to make it more readable #1419 by @iPazooki in #1422

New in Moq 4.20.69 (Aug 21, 2023)

  • Added:
  • `Mock<T>.RaiseAsync` method for raising "async" events, i.e. events that use a `Func<..., Task>` or `Func<..., ValueTask>` delegate.
  • `setup.Verifiable(Times times, [string failMessage])` method to specify the expected number of calls upfront. `mock.Verify[All]` can then be used to check whether the setup was called that many times. The upper bound (maximum allowed number of calls) will be checked right away, i.e. whenever a setup gets called.
  • Add `ThrowsAsync` methods for non-generic `ValueTask`
  • Fixed:
  • Verifying a protected generic method that returns a value is broken

New in Moq 4.18.4 (Dec 30, 2022)

  • Update package reference to `Castle.Core` (DynamicProxy) from version 5.1.0 to 5.1.1 (@stakx, #1317)

New in Moq 4.18.3 (Dec 5, 2022)

  • SetupAllProperties` crashes when invoked on a `Mock<T>` subclass (@mo-russo, #1278)

New in Moq 4.18.2 (Aug 2, 2022)

  • Update package reference to `Castle.Core` (DynamicProxy) from version 5.0.0 to 5.1.0 (@stakx, #1275)
  • Removed dependency on `System.Threading.Tasks.Extensions` for `netstandard2.1` and `net6.0` (@tibel, #1274)

New in Moq 4.18.1 (May 16, 2022)

  • Fixed:
  • Regression with lazy evaluation of `It.Is` predicates in setup expressions after updating from 4.13.1 to 4.16.1 (@b3go, #1217)
  • Regression with `SetupProperty` where Moq fails to match a property accessor implementation against its definition in an interface (@Naxemar, #1248)
  • Difference in behavior when mocking async method using `.Result` vs without (@cyungmann, #1253)

New in Moq 4.18.0 (May 12, 2022)

  • Changed:
  • Update package reference to `Castle.Core` (DynamicProxy) from version 4.4.1 to 5.0.0
  • Fixed:
  • Can't set up "private protected" properties
  • Using [...] an old version of `System.Net.Http` which is vulnerable to "DoS", "Spoofing", "Privilege Escalation", "Authentication Bypass" and "Information Exposure"
  • Failure when invoking a method with by-ref parameter & mockable return type on a mock with `CallBase` and `DefaultValue.Mock` configured

New in Moq 4.17.2 (Mar 6, 2022)

  • Fixed:
  • Regression: Property stubs not working on sub mock (@aaronburro, #1240)

New in Moq 4.17.1 (Feb 26, 2022)

  • Added:
  • `SetupSet`, `VerifySet` methods for `mock.Protected().As<>()` (@tonyhallett, #1165)
  • New `Throws` method overloads that allow specifying a function with or without parameters, to provide an exception, for example `.Throws(() => new InvalidOperationException())`
  • And `Setup(x => x.GetFooAsync(It.IsAny<string>()).Result).Throws((string s) => new InvalidOperationException(s))`. (@adam-knights, #1191)
  • Changed:
  • Update package reference to `Castle.Core` (DynamicProxy) from version 4.4.0 to 4.4.1 (@stakx, #1233)
  • Fixed:
  • The guard against unmatchable matchers (added in #900) was too strict; relaxed it to enable an alternative user-code shorthand `_` for `It.IsAny<>()` (@adamfk, #1199)
  • `mock.Protected()` setup methods fail when argument is of type `Expression` (@tonyhallett, #1189)
  • Parameter is invalid in `Protected().SetupSet()` ... `VerifySet` (@tonyhallett, #1186)
  • Virtual properties and automocking not working for `mock.Protected().As<>()` (@tonyhallett, #1185)
  • Issue mocking VB.NET class with overloaded property/indexer in base class (@myurashchyk, #1153)
  • Equivalent arrays don't test equal when returned from a method, making `Verify` fail when it should not (@evilc0, #1225)
  • Property setups are ignored on mocks instantiated using `Mock.Of` (@stakx, #1066)
  • * `SetupAllProperties` causes mocks to become race-prone (@estrizhok, #1231)

New in Moq 4.17.0 (Feb 13, 2022)

  • Added:
  • SetupSet`, `VerifySet` methods for `mock.Protected().As<>()` (@tonyhallett, #1165)
  • New `Throws` method overloads that allow specifying a function with or without parameters, to provide an exception, for example `.Throws(() => new InvalidOperationException())`
  • and `Setup(x => x.GetFooAsync(It.IsAny<string>()).Result).Throws((string s) => new InvalidOperationException(s))`. (@adam-knights, #1191)
  • Changed:
  • Update package reference to `Castle.Core` (DynamicProxy) from version 4.4.0 to 4.4.1 (@stakx, #1233)
  • Fixed:
  • The guard against unmatchable matchers (added in #900) was too strict; relaxed it to enable an alternative user-code shorthand `_` for `It.IsAny<>()` (@adamfk, #1199)
  • mock.Protected()` setup methods fail when argument is of type `Expression` (@tonyhallett, #1189)
  • Parameter is invalid in `Protected().SetupSet()` ... `VerifySet` (@tonyhallett, #1186)
  • Virtual properties and automocking not working for `mock.Protected().As<>()` (@tonyhallett, #1185)
  • Issue mocking VB.NET class with overloaded property/indexer in base class (@myurashchyk, #1153)
  • Equivalent arrays don't test equal when returned from a method, making `Verify` fail when it should not (@evilc0, #1225)

New in Moq 4.16.0 (Jan 16, 2021)

  • Changed:
  • Attempts to mark conditionals setup as verifiable are once again allowed; it turns out that forbidding it (as was done in #997 for version 4.14.0) is in fact a regression. (@stakx, #1121)
  • Fixed:
  • Performance regression: Adding setups to a mock becomes slower with each setup (@CeesKaas, #1110)
  • Regression: `mock.Verify[All]` no longer marks invocations as verified if they were matched by conditional setups. (@Lyra2108, #1114)

New in Moq 4.15.2 (Nov 26, 2020)

  • Upgraded `System.Threading.Tasks.Extensions` dependency to version 4.5.4 (@JeffAshton, #1108)

New in Moq 4.15.0 (Nov 10, 2020)

  • Added:
  • New method overloads for `It.Is`, `It.IsIn`, and `It.IsNotIn` that compare values using a custom `IEqualityComparer<T>` (@weitzhandler, #1064)
  • New properties `ReturnValue` and `Exception` on `IInvocation` to query recorded invocations return values or exceptions (@MaStr11, #921, #1077)
  • Support for "nested" type matchers, i.e. type matchers that appear as part of a composite type (such as `It.IsAnyType[]` or `Func<It.IsAnyType, bool>`). Argument match expressions like `It.IsAny<Func<It.IsAnyType, bool>>()` should now work as expected, whereas they previously didn't. In this particular example, you should no longer need a workaround like `(Func<It.IsAnyType, bool>)It.IsAny<object>()` as originally suggested in #918. (@stakx, #1092)
  • Changed:
  • Event accessor calls (`+=` and `-=`) now get consistently recorded in `Mock.Invocations`. This previously wasn't the case for backwards compatibility with `VerifyNoOtherCalls` (which got implemented before it was possible to check them using `Verify{Add,Remove}`). You now need to explicitly verify expected calls to event accessors prior to `VerifyNoOtherCalls`. Verification of `+=` and `-=` now works regardless of whether or not you set those up (which makes it consistent with how verification usually works). (@80O, @stakx, #1058, #1084)
  • Portable PDB (debugging symbols) are now embedded in the main library instead of being published as a separate NuGet symbols package (`.snupkg) (@kzu, #1098)
  • Fixed:
  • `SetupProperty` fails if property getter and setter are not both defined in mocked type (@stakx, #1017)
  • Expression tree argument not matched when it contains a captured variable – evaluate all captures to their current values when comparing two expression trees (@QTom01, #1054)
  • Failure when parameterized `Mock.Of<>` is used in query comprehension `from` clause (@stakx, #982)

New in Moq 4.14.7 (Oct 14, 2020)

  • Changed:
  • Mocks created by `DefaultValue.Mock` now inherit `SetupAllProperties` from their "parent" mock (like it says in the XML documentation) (@stakx, #1074)
  • Fixed:
  • Setup not triggered due to VB.NET transparently inserting superfluous type conversions into a setup expression (@InteXX, #1067)
  • Nested mocks created by `Mock.Of<T>()` no longer have their properties stubbed since version 4.14.0 (@vruss, @1071)
  • `Verify` fails for recursive setups not explicitly marked as `Verifiable` (@killergege, #1073)
  • `Mock.Of<>` fails for COM interop types that are annotated with a `[CompilerGenerated]` custom attribute (@killergege, #1072)

New in Moq 4.14.6 (Sep 30, 2020)

  • Fixed:
  • Regression since 4.14.0: setting nested non-overridable properties via `Mock.Of` (@mariotee, #1039)

New in Moq 4.14.5 (Jul 1, 2020)

  • Fixed:
  • Regression since version 4.11.0: `VerifySet` fails with `NullReferenceException` for write-only indexers (@Epicycle23, #1036)

New in Moq 4.14.4 (Jun 24, 2020)

  • Fixed:
  • Regression: `NullReferenceException` on subsequent setup if expression contains null reference (@IanYates83, #1031)

New in Moq 4.14.3 (Jun 18, 2020)

  • Fixed:
  • Regression, Part II: `Verify` behavior change using `DefaultValue.Mock` (@DesrosiersC, #1024)

New in Moq 4.14.2 (Jun 16, 2020)

  • Fixed:
  • Regression: Verify behavior change using DefaultValue.Mock (@DesrosiersC, #1024)

New in Moq 4.14.1 (Apr 28, 2020)

  • Added:
  • New `SetupSequence` verbs `.PassAsync()` and `.ThrowsAsync(...)` for async methods with `void` return type (@fuzzybair, #993)
  • Fixed:
  • `StackOverflowException` on `VerifyAll` when mocked method returns mocked object (@hotchkj, #1012)

New in Moq 4.14.0 (Apr 25, 2020)

  • Added:
  • A mock's setups can now be inspected and individually verified via the new `Mock.Setups` collection and `IInvocation.MatchingSetup` property (@stakx, #984-#987, #989, #995, #999)
  • New `.Protected().Setup` and `Protected().Verify` method overloads to deal with generic methods (@JmlSaul, #967)
  • Two new public methods in `Times`: `bool Validate(int count)` and `string ToString()` (@stakx, 975)
  • Changed:
  • Attempts to mark conditionals setup as verifiable are now considered an error, since conditional setups are ignored during verification. Calls to `.Verifiable()` on conditional setups are no-ops and can be safely removed. (@stakx, #997)
  • When matching invocations against setups, captured variables nested inside expression trees are now evaluated. Their values likely matter more than their identities. (@stakx, #1000)
  • Fixed"
  • Regression: Restored `Capture.In` use in `mock.Verify(expression, ...)` to extract arguments of previously recorded invocations. (@vgriph, #968; @stakx, #974)
  • Consistency: When mocking a class `C` whose constructor invokes one of its virtual members, `Mock.Of<C>()` now operates like `new Mock<C>()`: a record of such invocations is retained in the mock's `Invocations` collection (@stakx, #980)
  • After updating Moq from 4.10.1 to 4.11, mocking NHibernate session throws a `System.NullReferenceException` (@ronenfe, #955)

New in Moq 4.13.0 (Sep 2, 2019)

  • Changed:
  • Improved error message that is supplied with `ArgumentException` thrown when `Setup` or `Verify` are 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)
  • Consisent `Callback` delegate validation regardless of whether or not `Callback` is preceded by a `Returns`: Validation for post-`Returns` callback delegates used to be very relaxed, but is now equally strict as in the pre-`Returns` case.) (@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]` and `Verify[Add|Remove|All]` (@lepijohnny, #825)
  • Added support for lambda expressions while creating a mock through `new Mock<SomeType>(() => new SomeType("a", "b"))` and `repository.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 type
  • `It.IsSubtype<T>` — matches `T` and proper subtypes of `T`
  • `It.IsValueType` — matches only value types
  • You can create your own custom type matchers:
  • ```csharp
  • [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 `IInvocation` representing 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`, the `argument` received 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 parameter `parameterType`. (@stakx, #908)
  • Fixed:
  • Moq does not mock explicit interface implementation and `protected virtual` correctly. (@oddbear, #657)
  • `Invocations.Clear()` does not cause `Verify` to fail (@jchessir, #733)
  • Regression: `SetupAllProperties` can no longer set up properties whose names start with `Item`. (@mattzink, #870; @kaan-kaya, #869)
  • Regression: `MockDefaultValueProvider` will no longer attempt to set `CallBase` to true for mocks generated for delegates. (@dammejed, #874)
  • * `Verify` throws `TargetInvocationException` instead of `MockException` when 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: `SetupAllProperties` removes indexer setups. (@stakx, #901)
  • Parameter types are ignored when matching an invoked generic method against setups. (@stakx, #903)
  • For `[Value]Task<object>`, `.ReturnsAsync(null)` throws `NullReferenceException` instead of producing a completed task with result `null` (@voroninp, #909)

New in Moq 4.12.0 (Jun 20, 2019)

  • Changed:
  • Improved performance for `Mock.Of<T>` and `mock.SetupAllProperties()` as the latter now performs property setups just-in-time, instead of as an ahead-of-time batch operation. (@vanashimko, #826)
  • Setups with no `.Returns(…)` nor `.CallBase()` no longer return `default(T)` for loose mocks, but a value that is consistent with the mock's `CallBase` and `DefaultValue[Provider]` settings. (@stakx, #849)
  • Added:
  • New method overload `sequenceSetup.ReturnsAsync(Func<T>)` (@stakx, #841)
  • LINQ to Mocks support for strict mocks, i.e. new method overloads for `Mock.Of`, `Mocks.Of`, `mockRepository.Of`, and `mockRepository.OneOf` that accept a `MockBehavior` parameter. (@stakx, #842)
  • Fixed:
  • Adding `Callback` to a mock breaks async tests (@marcin-chwedczuk-meow, #702)
  • `mock.SetupAllProperties()` now setups write-only properties for strict mocks, so that accessing such properties will not throw anymore. (@vanashimko, #836)
  • Regression: `mock.SetupAllProperties()` and `Mock.Of<T>` fail due to inaccessible property accessors (@Mexe13, #845)
  • Regression: `VerifyNoOtherCalls` causes stack overflow when mock setup returns the mocked object (@bash, #846)
  • `Capture.In()` no longer captures arguments when other setup arguments do not match (@ocoanet, #844).
  • `CaptureMatch` no longer invokes the capture callback when other setup arguments do not match (@ocoanet, #844).

New in Moq 4.10.1 (Dec 4, 2018)

  • Fixed:
  • 'NullReferenceException` when using `SetupSet` on indexers with multiple parameters (@idigra, #694)
  • `CallBase` should not be allowed for delegate mocks (@tehmantra, #706)
  • Changed::
  • Dropped the dependency on the `System.ValueTuple` NuGet package, at no functional cost (i.e. value tuples are still supported just fine) (@stakx, #721)
  • Updated failure messages to show richer class names (@powerdude, #727)
  • Upgraded `System.Reflection.TypeExtensions` and `System.Threading.Tasks.Extensions` dependencies to versions 4.5.1 (@stakx, #729)

New in Moq 4.10.0 (Sep 8, 2018)

  • Added:
  • `ExpressionCompiler`: An extensibility point for setting up alternate LINQ expression tree compilation strategies (@stakx, #647)
  • `setup.CallBase()` for `void` methods (@stakx, #664)
  • `VerifyNoOtherCalls` for `MockRepository` (@BlythMeister, #682)
  • Changed:
  • Make `VerifyNoOtherCalls` take into account previous calls to parameterless `Verify()` and `VerifyAll()` (@stakx, #659)
  • **Breaking change:** `VerifyAll` now succeeds after a call to `SetupAllProperties` even when not all property accessors were invoked (stakx, #684)
  • Fixed:
  • More precise `out` parameter detection for mocking COM interfaces with `[in,out]` parameters (@koutinho, #645)
  • Prevent false 'Different number of parameters' error with `Returns` callback methods that have been compiled from `Expression`s (@stakx, #654)
  • `Verify` exception should report configured setups for delegate mocks (@stakx, #679)
  • `Verify` exception should include complete call expression for delegate mocks (@stakx, #680)
  • Bug report #556: "Recursive setup expression creates ghost setups that make `VerifyAll` fail" (@stakx, #684)
  • Bug report #191: "Upgrade from 4.2.1409.1722 to 4.2.1507.0118 changed `VerifyAll` behavior" (@stakx, #684)

New in Moq 4.9.0 (Jul 14, 2018)

  • New:
  • Added `Mock.Invocations` property to support inspection of invocations on a mock (@Tragedian, #560)
  • Changes:
  • Update package reference to `Castle.Core` (DynamicProxy) from version 4.3.0 to 4.3.1 (@stakx, #635)
  • Floating point values are formatted with higher precision (satisfying round-tripping) in diagnostic messages (@stakx, #637)
  • Fixed:
  • `CallBase` disregarded for some base methods from non-public interfaces (@stakx, #641)
  • Obsoleted:
  • `mock.ResetCalls()` has been deprecated in favor of `mock.Invocations.Clear()` (@stakx, #633)

New in Moq 4.8.3 (Jun 10, 2018)

  • Added:
  • Add ISetupSequentialResult<TResult>.Returns method overload that support delegate for deferred results (@snrnats, #594)
  • Support for C# 7.2's in parameter modifier (@stakx, #624, #625)
  • Missing methods ReturnsAsync and ThrowsAsync for sequential setups of methods returning a ValueTask (@stakx, #626)
  • Changed:
  • Breaking change: All ReturnsAsync and ThrowsAsync setup methods now consistently return a new Task on each invocation (@snrnats, #595)
  • Speed up Mock.Of<T>() by approx. one order of magnitude (@informatorius, #598)
  • Update package reference to Castle.Core (DynamicProxy) from version 4.2.1 to 4.3.0 (@stakx, #624)
  • Fixed:
  • Usage of ReturnsExtensions.ThrowsAsync() can cause UnobservedTaskException (@snrnats, #595)
  • ReturnsAsync and ThrowsAsync with delay parameter starts timer at setup (@snrnats, #595)
  • Returns regression with null function callback (@Caraul, #602)

New in Moq 4.8.1 (Jan 9, 2018)

  • Added:
  • C# 7 tuple support for `DefaultValue.Empty` and `DefaultValue.Mock` (@stakx, #563)
  • Changed:
  • Downgraded `System.Threading.Tasks.Extensions` and `System.ValueTuple` dependencies to versions 4.3.0 as suggested by @tothdavid in order to improve Moq compatibility with .NET 4.6.1 / help prevent `MissingMethodException` and similar (@stakx, #571)
  • Fixed:
  • `CallBase` regression with explicitly implemented interface methods (@stakx, #558)