Giter VIP home page Giter VIP logo

fluentvalidation.validators.unittestextension's Introduction

FluentValidation.Validators.UnitTestExtension

Build Status Downloads

Full documentation

Project description

Main purpose of this small library is to extend and simplify possibilities of testing code that is using FluentValidation package.

Installation - NuGet Packages

Install-Package FluentValidation.Validators.UnitTestExtension

Overview

This library allows you to focus on testing your implementation. You will be able to write test that will run faster, will be readable and will test only your implementation.

Please look at the following example of PersonValidator:

public class PersonValidator : AbstractValidator<Person>
{
  public PersonValidator()
  {
    RuleFor(person => person.Name).NotNull();
  }
}

By using this library you can write unit test like this:

public class PersonValidatorTests
{
  [Fact]
  public void When_PersonValidatorConstructing_Then_RulesAreConfiguredCorrectly()
  {
    var personValidator = new PersonValidator();

    personValidator.ShouldHaveRules(x => x.Name,
      BaseVerifiersSetComposer.Build()
        .AddPropertyValidatorVerifier<NotNullValidator<Person, string>>()
	.Create());
  }
}

According to FluentValidation wiki same code should be tested in the following way:

public class PersonValidatorTests
{
  private PersonValidator validator;

  public void PersonValidatorTester()
  {
    validator = new PersonValidator();
  }

  [Fact]
  public void Should_have_error_when_Name_is_null() 
  {
    var model = new Person { Name = null };
    var result = validator.TestValidate(model);
    result.ShouldHaveValidationErrorFor(person => person.Name); 
  }

  [Fact]
  public void Should_not_have_error_when_name_is_specified()
  {
    var model = new Person { Name = "Jeremy" };
    var result = validator.TestValidate(model);
    result.ShouldNotHaveValidationErrorFor(person => person.Name);
  }
}

As you can see you need to test each scenario that can fail validation with FluentValidation approach. With that approach you are writing rather integration test than real unit test. Your tests will be slower and you will need to write more code.

By using this framework you will be:

  • more effective in writing unit tests
  • you will be testing only your code
  • your test will be more robustness
  • moreover you will be able to check order of validators
  • and many more.

Please see documentation.

fluentvalidation.validators.unittestextension's People

Contributors

michaljankowskii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fluentvalidation.validators.unittestextension's Issues

AddChildValidatorVerifier error

The AddChildValidatorVerifier generic types doesn't seem to be properly working. The first generic "T" should be the type of the child validator and the second type "TProperty" should be the type of the child. Neither values seem to be working right now as I got an error saying that "T" needed to be the type of the parent, not the child validator. When I set "T" as the type of the parent, I get a different error about that not being a validator type.

I am using a RuleForEach() in this case as the child type is a list of types.

Testing When and Unless rules

I have conditional rules on most of my validators but I'm not sure how I'd test these. For example the Comment and CommentStatus values are only required when HasComment is true.

public class MyModel
{
    public bool? HasComment { get; set; } // radio button with neither option selected by default

    public string Comment { get; set; }

    public int? CommentStatus { get; set; } // drop down with 5 values and an unselected option
}

public class MyModelValidator : AbstractValidator<MyModel>
{
    public MyModelValidator()
    {
        RuleFor(m => m.HasComment).NotNull();

        When(m => m.HasComment.GetValueOrDefault(), () =>
        {
            RuleFor(m => m.Comment).NotEmpty();
            RuleFor(m => m.CommentStatus).NotNull();
        });

        RuleFor(m => m.Comment).MaximumLength(1000);
        RuleFor(m => m.CommentStatus).GreaterThanOrEqualTo(1)
                                     .LessThanOrEqualTo(5);
    }
}

I also have them on the properties directly like so:

public class MyModelValidator : AbstractValidator<MyModel>
{
    public MyModelValidator()
    {
        RuleFor(m => m.HasComment).NotNull();

        RuleFor(m => m.Comment).NotEmpty()
                               .When(m => m.HasComment.GetValueOrDefault());
        RuleFor(m => m.Comment).MaximumLength(1000);

        RuleFor(m => m.CommentStatus).NotNull()
                                     .When(m => m.HasComment.GetValueOrDefault());
        RuleFor(m => m.CommentStatus).GreaterThanOrEqualTo(1)
                                     .LessThanOrEqualTo(5);
    }
}

How to UnitTest DependentRules

Hi,

We are using this unit test extension in order to validate if the rules are configured:

_validator.ShouldHaveRules(x => x.IdentityId, BaseVerifiersSetComposer.Build() .AddPropertyValidatorVerifier<NotNullValidator>() .AddPropertyValidatorVerifier<NotEmptyValidator>() .Create());

Is it possible to validate in a similar way when we have DependentRules configured?
I've been not able to solve that

Thanks,
Jaume

Incorrect EnumValidator field name in EnumValidatorVerifier

typeof(EnumValidator).GetField("enumType", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumValidator).Should().Be(this.enumType, "(EnumType field)");

I believe that instead of enumType it should be _enumType as in FluentValidations the private field name is _enumType.
Currently I get a System.NullReferenceException : Object reference not set to an instance of an object. exception on the aforementioned line. Adding the underscore seems to fix the issue.

Include testing extensions as part of the main FV project?

As I mentioned on Twitter I thought it might be worth considering incorporating these test extensions in the main FV project.

This would mean we could provide a unified testing experience rather than having both the current test helpers and your project.

The downside would be that you’d end up being limited to my release schedule as I release all the FV packages together.

Either way, I’ll add a section to the testing page on the FV that points users here for more info.

Let me know what you think.

Incompatible with FluentValidation 9.0.0

When updating FluentValidation to Version 9.0.0 the tests with this extension no longer work.

Message: 
    System.TypeLoadException : Could not load type 'FluentValidation.Validators.IDelegatingValidator' 
    from assembly 'FluentValidation, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7de548da2fbae0f0'.
  Stack Trace: 
    <>c__DisplayClass0_0`2.<ShouldHaveRules>b__3(IPropertyValidator propertyValidator)
    List`1.ForEach(Action`1 action)
    AbstractValidatorExtension.ShouldHaveRules[T,TProperty](AbstractValidator`1 validator, 
    Expression`1 expression, IValidatorVerifier[] validatorVerifieres)
    AppRegisterDtoValidatorTests.ConcurrencyStamp_ShouldHaveAllValidators() line 19

how add test for InlineValidator

Here is my configuration of my Fluent validation

var workflowListContactMessage = new InlineValidator();

        workflowListContactMessage.RuleFor(x => x.SequenceNo)
            .GreaterThan(0)
            .WithMessage(MissingInfo);

RuleForEach(x => x.WorkflowListContacts)
.SetValidator(workflowListContactMessage);

Currently i am adding test to validate if there exits an InlineValidator

AssociateWorkflowListContactCommandValidator.ShouldHaveRules(x => x.WorkflowListContacts,
BaseVerifiersSetComposer.Build()
.AddChildValidatorVerifier<InlineValidator>()
.Create());

I want to know how do i check if the inline validator has a validation rule for SequenceNo

Length(5, 20) TotalLength Invalid

Hello, please ask a question about Length validation rules. Total Length input character length is not recognized. How should we use it?

Testing validation on a related property

Hi,

More of a question than issue....

I've just came across your library and was wondering how you test a validation for this scenario

class Box { int height; int width }

The validator would look something like

RuleFor(p => p.height).GreaterThan(q => q.width).WithMessage("height must be greater than width")

Have I missed something or is there not an overload for passing in a property via an expression?

.AddPropertyValidatorVerifier<GreaterThanValidator>(0)

How do test using 'Must'

RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");

I could test that it runs the PredicateValidator, but it would be good to check if it uses the correct Func as well (in this case BeAValidPostcode).

something like
validator.ShouldHaveRules(x => x.External,
BaseVerifiersSetComposer.Build()
.AddPropertyValidatorVerifier(validator.BeAValidPostcode)
.Create());

How do you use this to test using 'Must'

RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");

I could test that it runs the PredicateValidator, but it would be good to check if it uses the correct Func as well (in this case BeAValidPostcode).

Rules of independent properties are expected in tested property

Hello,

in the code underneath I try to check if the validation rule GreaterThan(0) for the id of the Driver object in a Shift is present. Unfortunately the test always fails with the message: Expected collection to contain 1 item(s) because (number of rules for property), but found 3.

It seems like somehow the rules for Assistant.Id and Trainee.Id influence the ones for Driver.Id.

public class BugTests
{
	private readonly DutyRosterValidator dutyRosterValidator =
	  new DutyRosterValidator();

	[Test]
	public void DriverId_ShouldHaveAllValidators()
	{
		dutyRosterValidator.ShouldHaveRules(x => x.Driver.Id,
			BaseVerifiersSetComposer.Build()
				.AddPropertyValidatorVerifier<GreaterThanValidator>(0)
				.Create());
	}

	public class User
	{
		public int Id { get; set; }
	}

	public class Shift
	{
		public DateTime StartTime { get; set; }

		public DateTime EndTime { get; set; }

		public User Driver { get; set; }

		public User Assistant { get; set; }

		public User Trainee { get; set; }
	}

	public class DutyRosterValidator : AbstractValidator<Shift>
	{
		public DutyRosterValidator()
		{
			RuleFor(x => x.Driver.Id)
				.GreaterThan(0)
				.When(x => x.Driver != null);

			RuleFor(x => x.Assistant.Id)
				.GreaterThan(0)
				.When(x => x.Assistant != null);

			RuleFor(x => x.Trainee.Id)
				.GreaterThan(0)
				.When(x => x.Trainee != null);
		}
	}
}

Broken with FluentValidation Version 10.0.0.0

Erro:

System.TypeLoadException : Could not load type 'FluentValidation.Validators.ScalePrecisionValidator' from assembly 'FluentValidation, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7de548da2fbae0f0'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.