nunit

Write a custom constraint for the constraint model

Match an integer approximatively

Suppose we want to write a constraint which matches a number, but approximatively. Say, you are supposed to have 95 people in a survey, but 93 or 96 will do as well. We can write a custom constraint of the form:

public class AlmostEqualToConstraint : Constraint
{
    readonly int _expected;
    readonly double _expectedMin;
    readonly double _expectedMax;
    readonly int _percentageTolerance;


    public AlmostEqualToConstraint(int expected, int percentageTolerance)
    {
        _expected = expected;
        _expectedMin = expected * (1 - (double)percentageTolerance / 100);
        _expectedMax = expected * (1 + (double)percentageTolerance / 100);                    
        _percentageTolerance = percentageTolerance;
        Description = $"AlmostEqualTo {expected} with a tolerance of {percentageTolerance}%";
    }


    public override ConstraintResult ApplyTo<TActual>(TActual actual)
    {
        if (typeof(TActual) != typeof(int))
            return new ConstraintResult(this, actual, ConstraintStatus.Error);

        var actualInt = Convert.ToInt32(actual);

        if (_expectedMin <= actualInt && actualInt <= _expectedMax)
            return new ConstraintResult(this, actual, ConstraintStatus.Success);
        else
            return new ConstraintResult(this, actual, ConstraintStatus.Failure);
    }
}

Make new constraint usable in a fluent context

We’re going to integrate the AlmostEqualToConstraint with the fluent NUnit interfaces, specifically the Is one. We’ll need to extend the NUnit provided Is and use that throughout our code.

public class Is : NUnit.Framework.Is
{
    public static AlmostEqualToConstraint AlmostEqualTo(int expected, int percentageTolerance = 5)
    {
        return new AlmostEqualToConstraint(expected, percentageTolerance);
    }
}

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow