Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent Assertions: Approximately compare a classes properties

I have a class Vector3D that has the properties X, Y and Z of type double (it also has other properties such as Magnitude).

What is the best way of approximately comparing all the properties or a selection of the properties at a given precision using Fluent Assertions?

Currently I have been doing it like this:

calculated.X.Should().BeApproximately(expected.X, precision);
calculated.Y.Should().BeApproximately(expected.Y, precision);
calculated.Z.Should().BeApproximately(expected.Z, precision);

Is there a single line approach that will achieve the same thing? Such as using ShouldBeEquivalentTo, or does this require constructing a generic extension method that allows properties to be included / excluded?

like image 957
Ayb4btu Avatar asked Apr 22 '16 01:04

Ayb4btu


People also ask

Should I use fluent Assertions?

Fluent Assertions are important in unit testing because they allow the code to be easily read and followed. This makes it easier to determine whether or not an assertion is being met. As a result, everyone can easier read and understand unit tests, making it easier to locate the failing assert.

What is fluent Assertions C#?

Fluent Assertions is a set of . NET extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style unit test.


1 Answers

Yes it's possible using ShouldBeEquivalentTo. The following code will check all properties that are of type double with a precision of 0.1 :

double precision = 0.1;
calculated.ShouldBeEquivalentTo(expected, options => options
    .Using<double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, precision))
    .WhenTypeIs<double>());

If you want to compare only the X, Y and Z properties change the When constraint like this :

double precision = 0.1;
calculated.ShouldBeEquivalentTo(b, options => options
    .Using<double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, precision))
    .When(info => info.SelectedMemberPath == "X" ||
                  info.SelectedMemberPath == "Y" ||
                  info.SelectedMemberPath == "Z"));

Another approach is to explicitly tell to FluentAssertions which properties should be compared, but it's a bit less elegant :

double precision = 0.1;
calculated.ShouldBeEquivalentTo(b, options => options
    .Including(info => info.SelectedMemberPath == "X" ||
                       info.SelectedMemberPath == "Y" ||
                       info.SelectedMemberPath == "Z")
    .Using<double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, precision))
    .When(info => true));

Since the Using statement does not return a EquivalencyAssertionOptions<T> we need to hack it by calling the When statement with an always true expression.

like image 132
Fabien ESCOFFIER Avatar answered Sep 22 '22 17:09

Fabien ESCOFFIER