Hi. I'm attempting to use It.Is<>
outside of Setup
but it seems to be returning null - I assume due to relying on knowing the current method. I was trying to add some code to remove boilerplate where the only thing changing is an argument (and condition expression) to a method call. Something like:
var mockCommandBus = new Mock<ICommandBus>();
mockCommandBus
.Setup(_ => _.PublishAsync(
testCommand,
It.IsAny<CancellationToken>()))
.ReturnsAsync(result);
return (mockCommandBus.Object, mockCommandBus);
Called:
CommandBusBuilder.BuildMockCommandCall(
It.Is<RegisterNewApplication>(_ => _.Name == name && _.Description == description),
Result.Ok(new ApplicationId(id)));
Setup
. Anyone got any thoughts on this? Alternatives? I'm trying to avoid constantly writing the first block.
It.Is
and other matchers only work when used inside LINQ expression tree. What's important is their identity, so to speak, and that is only preserved in a LINQ expression tree. Once evaluated, that is gone and all ypu're left with is their retuen value, which is in fact completely irrelevant & ignored by Moq.
Expression.*
factory methods which is going to be a pain in the b*tt compared to the C# compiler doing that for you automagically.
Span<T>
and other by-ref-like types due to limitations in .NET Reflection and LINQ expression trees. No way around it unfortunately.
sequenceSetup.ReturnsRange(Enumerable.Repeat(lastValue, int.MaxValue))
though that hasn't been implemented. We've briefly discussed this in moq/moq4#573.
mock.SetReturnsDefault
. (Though take note that this is not specific to one method setup, but to all of a mock's methods.)
Arguments
get boxed as object
s (boxing isn't allowed for by-ref structs, i.e. stack-only types). But as far as my current understanding of Moq 5 goes, that at least would be a limitation caused by its own API, and not by the underlying technology.
Type
, MethodInfo
etc. Try to do something with the much lower-level System.Reflection.Metadata or Mono.Cecil, and you'll soon see what System.Reflection provides beyond those. Like other parts in the BCL (say, LINQ expression trees, or CodeDOM), Reflection would ideally be updated together with C# language innovation... and that hasn't fully happened for quite a few years now. For example, try DynamicInvoke
-ing a delegate that has spans in its signature; or try reflecting over all the custom modifiers that the C# compiler rmits these days. Yes, Reflection isn't the only limiting factor. You're already aware of some LINQ expression tree limitations (no assignment, no async
/await
, no default parameters, etc.) though Moq 4 can partly work around rhose. But at the end of the day, those parts of the BCL lag behind Roslyn.