TUnit.Mocks - Feedback · thomhurst/TUnit · Discussion #4981 (original) (raw)
As a user of Moq, I always disliked, having to specify those It.IsAny<TheExactType>() for all method parameters. Since TUnit.Mocks is source generated, I think it should be possible to come up with a more convenient API.
For example instead of this...
var equalityComparer = Mock.Of<IEqualityComparer>(); var equals = equalityComparer.Equals_(Arg.Any(), Arg.Is(b => b > 0)).Returns((a, b) => a == b); // ... some testing code ... await Assert.That(equals).WasCalled(Times.Once);
... this might be an alternative:
var equalityComparer = Mock.Of<IEqualityComparer>(); var equals = equalityComparer.SetupEquals((a, b) => a == b, if: (_, b) => b > 0); // ... some testing code ... await Assert.That(equals).WasCalled(Times.Once);
It is not necessary the best way to do it and it will need some refinement, but I think it is already better than the classical syntax.
A few points to think about:
- A nice property of this syntax is, that normal C# rules, that everyone knows, apply. For example if there is no overload conflict, lambda argument types do not have to be specified. However, if there is a conflict, everyone will naturally understand, that the fix is changing
(a, b) => ...to(int a, int b) => ... - Just
MethodName(lambda)does not describe well, what happens. Probably something likeSetupMethodName(lambda)orMethodNameReturns(lambda)is better. And as an upside, it will reduce naming conflicts (In the example above no more Equals_). - Maybe the parameters of the mock method body lambda should not be the actual values, but wrappers instead. Then one might be able to write something like
(a, b) => b > 0 ? a == b : SetupResult<int>.NotSetUp. The return value would be a discriminated union, so that either a result could be returned, or a marker that the setup does not apply in this case, or maybe even an assertion result? - It might be a good idea to eliminate all the Verify-Methods and instead integrate it into the TUnit Assert API.