tony09uk
tony09uk

Reputation: 2991

how to test fluent validations error message

I am trying to get to grips with TDD, I have reviewed some tutorials and am trying to implement tests on my validation classes that I have created using fluent validation.

public SomeFormValidator()
{
        RuleFor(x => x.MyClass).NotNull()
            .WithMessage("MyClass cannot be null");
}

I have looked at the TDD examples specifically for fluent validation and created a couple of tests

    [Test]
    public void Should_have_error_when_MyClass_is_null()
    {
        MyClass myClass = null;
        SomeFormValidator.ShouldHaveValidationErrorFor(aup => aup.MyClass, myClass);
    }

    [Test]
    public void Should_not_have_error_when_MyClass_is_not_null()
    {
        MyClass myClass = new MyClass();
        SomeFormValidator.ShouldNotHaveValidationErrorFor(aup => aup.MyClass, myClass);
    }

I would like to now test that the string "MyClass cannot be null" is returned when it is null. I have not been able to find anything covering returned message and I have not been able to work it out.

Upvotes: 2

Views: 3725

Answers (2)

tony09uk
tony09uk

Reputation: 2991

Thanks to the guidance of @Surgey I was able to come up with a solution that uses the fluent validation built in methods, in addition to that I have been able to better layout my test which I have added below

using FluentValidation.TestHelper;
using NUnit.Framework;
using MyProject.Models...
using MyProject...

namespace MyProject.Tests.Classes.Validation
{
[TestFixture]
public class SomeFormValidatorTest
{
    private SomeFormValidator SomeFormValidator;

    [SetUp]
    public void Setup()
    {
        SomeFormValidator = new SomeFormValidator();
    }

    [Test]
    public void Should_display_correct_error_message_MyClass_is_null()
    {
        //arrange
        MyClass myClass = null;

        //act
        var result = SomeFormValidator.ShouldHaveValidationErrorFor(x => x.MyClass, myClass);

        //assert
        result.WithErrorMessage("MyClass is required");

        //first attempt prior to finding WithErrorMessage exists
        //foreach (var r in result)
        //{
        //    Assert.AreEqual("MyClass is required", r.ErrorMessage);
        //}
    }
}

}

I am using result.WithErrorMessage as that is was is provided in the result but I have left the foreach in, but commented, as I find the error message produced by using Assert.AreEqual produce a better message in the test runner.

Upvotes: 5

Serhii Shushliapin
Serhii Shushliapin

Reputation: 2708

There is Arrange-Act-Assert (AAA) technique that helps to structure unit tests properly.

Arrange

First of all, you need to create a System Under Test (SUT) and inputs. In this case that are SomeFormValidator and SomeForm instances:

  // arrange
  var sut = new SomeFormValidator();
  var someFormWithNullProp = new SomeForm { MyClass = null };

Act

Then you need to call the SUT to perform real work. For validators, that is the Validate() method call:

  // act
  ValidationResult result = sut.Validate<SomeForm>(someFormWithNullProp);

Assert

The last part of the unit test checks if the actual result matches the expectations:

  // assert
  Assert.False(result.IsValid);
  Assert.AreEqual(
    "MyClass cannot be null",
    result.Errors.Single().ErrorMessage);

Upvotes: 3

Related Questions