question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New methods for testing validators: ShouldPass/Only

See original GitHub issue

Is your feature request related to a problem? Please describe.

We are using FluentValidation quite intensively, and write lots of tests for our validators. That’s why we came up with shorter and (I want to believe) more expressive syntax for asserting the behavior of our validators.

If you agree with the approach in general, I will go ahead and create a pull request so that more people could benefit from that syntax.

The current approach for positive assertions which is used in FluentValidation itself and can be considered recommended, looks like this:

    var result = validator.Validate(validaInstance);
    result.IsValid.ShouldBeTrue();

The issue is, when the validation unexpectedly fails, this test does not give any information on what errors were raised, and we need to do manual debugging to find the reason.

For testing negative scenario, if we want to assert that only a single error was raised, we can use this approach:

    var result = validator.Validate(invalidInstance);
    result.Errors.Single().ErrorMessage.ShouldEqual("I am a bad guy!");

But again, in case of an unexpected error, there will be just Sequence contains more than one element, and we need to debug to find a culprit.

Describe the solution you’d like

What we did was to add a couple of extension methods that check if the validation succeeded, verify that error messages match the expectation (when provided), and in case of a failure, output the detailed information about which errors were expected, which unexpectedly occurred, and which did not occur though expected.

In code, it looks like this:

    validator.TestValidate(validInstance).ShouldPass();
    validator.TestValidate(invalidInstance).ShouldFail(); // Here we do not care about the exact messages
    validator.TestValidate(invalidInstance).ShouldFail("The nose is too long"); // If we expect a single message
    validator.TestValidate(invalidInstance).ShouldFail("The nose is too long", "The eyes are too square", ...); // If we expect more than one message

The latter, with multiple error messages, is not of wide use because we usually test one rule in a single test, but still this can be useful.

What this syntax does not support is verification of property names, error severity, etc. As well as it does not let you specify “I need to check that this error is raised, but there may be more, I don’t care”. But for this, the existing methods (ShouldHaveValidationErrorFor and similar) work perfectly, we are not proposing to do anything with them.

Describe alternatives you’ve considered

Initially, we used the approach very similar to what is used within FluentValidation for unit tests, but then switched to this new syntax as it is shorter and, well, more Fluent.

Additional Context

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
JeremySkinnercommented, Sep 1, 2021

Sounds good, thanks! I’m away on holiday from Friday and will be unavailable for a couple of weeks, but will do my best to review when I’m back

0reactions
JeremySkinnercommented, Sep 17, 2021

Merged for 11.0 release

Read more comments on GitHub >

github_iconTop Results From Across the Web

Test Extensions — FluentValidation documentation
You can use the TestValidate extension method to invoke a validator for testing purposes, and then perform assertions against the result.
Read more >
The Best Guide to Validation Testing
Verification uses methods like reviews, walkthroughs, inspections and desk-checking while validation uses methods like black-box testing, white ...
Read more >
Get validators present in FormGroup/FormControl
The hasValidator() method only works for validators that 'fail' (eg. a required validator on a control with the value '' (empty)). Since if...
Read more >
Testing complex forms - Testing Angular
How to test the logic and accessibility of Angular Reactive Forms.
Read more >
Angular Custom Form Validators: Complete Guide
All about custom form validators, including synchronous and asynchronous, field-level, form-level, for both template-driven and reactive forms.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found