-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot mock some things becuase they are extension methods #191
Comments
I really wouldn't recommend this approach. Don't try and mock individual aspects of FV...either hide the entirety of FV Mocking in this ay tends to lead to very brittle tests, so I'd suggest avoiding it |
Thanks for that. I ended up going that way and just using the actual validator instances in the business logic that was using it. Is that what you meant? OR am I misunderstanding your comment. |
Could you please elaborate on this? So far I can easily mock validators derived from AbstractValidator. As long as I am not using RuleSet's... Unfortunately using real validators in unit tests is cumbersome due to fact that they do have additional dependencies that needs to me mocked. |
Mocking is for testing how your code interacts with a particular contract or protocol. As an example, if you have some code that interacts with a web service and you want to test how your code acts depends on different responses from this service, then you'd extract the true implementation of the web service API behind an interface (the contract), and supply a mock version that can supply different results in your test. This is an appropriate use of mocking as you're testing the interaction with a contract (the interface) not a concrete implementation. Don't mock classes. A class is not a contract- it's an implementation. This means it's subject to change, you end up relying on internal behaviour and your tests become brittle. As I mentioned above, I'd suggest using the real validator instances in your tests. If this really won't work for you then define an interface contract for validation, hide FluentValidation behind this and mock this in your tests. Or mock IValidator[T], but don't mock FV classes directly. Edit: Please also note that the extension methods for rulesets are only wrappers for developer convenience. They are completely optional and you can use rulesets without these extension methods by just building up a ValidationContext and passing it to the Validate method: https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation/DefaultValidatorExtensions.cs#L819 |
I don't :). I am mocking IValidator. Which lack easy way of mocking RuleSet calls. Since they are dispatched via extension.
I saw this way when I was digging into extension methods. I don't want to use this approach exactly because extension methods exists: it is requires more code to use it. And what is more important: mocking & putting expectation on IValidator.Validate(ValidationContext context) method is much more complicated. At the moment I am using following mock when rule sets are used:
However with this approach I am lacking check on rule name. I may mock it that way with rule name check:
But this is fall under 'do not depend on internal behavior of library'. |
I notice that you do have a IValidator which is great because I can mock them in a unit test. But for some of the documented methods they are extension methods in DefaultValidatorExtensions.
Is there a particular reason for this? What I want to be able to do is test my business service to ensure the correct rule is being applied without acutally having to have the instance (just using a mock). For example using Moq and Xunit I have a test like this:
This is not possible however since the overload with ruleSet parameter is a static extension method... Is there any reason why it couldn't be on the IValidator interface?
Incidentally that was the mistake I had make in the other issue I opened.. Not including FluentValidation namespace correctly.
The text was updated successfully, but these errors were encountered: