bitbonk
bitbonk

Reputation: 49659

Assert that two objects are exactly equivalent

In the simple example below I try do find a single Should() assertion that makes the test pass and fail the way I described in the comments. The one that I currently use result.ShouldBeEquivalentTo(expectedResult, o => o.RespectingRuntimeTypes()) does not fail for the last two tests. The goal is that result and excpectedResult should always have exactly the same types and values.

using System;
using System.Linq;
using FluentAssertions;
using Xunit;

public class ParserTests
{
    // The test that should be failing will be removed once the correct Should() is found
    [Theory,
    InlineData(DataType.String, "foo", "foo"), // should pass
    InlineData(DataType.Integer, "42", 42),  // should pass
    InlineData(DataType.ByteArray, "1,2,3", new byte[] { 1, 2, 3 }),  // should pass
    InlineData(DataType.ByteArray, "1,2,3", new byte[] { 3, 2, 1 }),  // should fail
    InlineData(DataType.ByteArray, "1,2,3", new double[] { 1.0, 2.0, 3.0 }),  // should fail, but doesn't
    InlineData(DataType.Integer, "42", 42.0d)]  // should fail, but doesn't
    public void ShouldAllEqual(DataType dataType, string dataToParse, object expectedResult)
    {
        var result = Parser.Parse(dataType, dataToParse);

        result.ShouldBeEquivalentTo(expectedResult, o => o.RespectingRuntimeTypes());

        // XUnit's Assert seems to have the desired behavior
        // Assert.Equal(result, expectedResult);
    }
}

// Simplified SUT:
public static class Parser
{
    public static object Parse(DataType datatype, string dataToParse)
    {
        switch (datatype)
        {
            case DataType.Integer:
                return int.Parse(dataToParse);

            case DataType.ByteArray:
                return
                    dataToParse.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(byte.Parse)
                        .ToArray();

            default:
                return dataToParse;
        }
    }
}

public enum DataType
{
    String,
    Integer,
    ByteArray
}

Upvotes: 0

Views: 761

Answers (1)

NPras
NPras

Reputation: 4125

That's the thing with Equivalency - it's not Equality (which is what you're trying to test for).

The only way I could think of that would satisfy your code would be to do:

if (result is IEnumerable)
    ((IEnumerable)result).Should().Equal(expectedResult as IEnumerable);
else
    result.Should().Be(expectedResult);

I havent used FluentAssertions extensively, so I'm not aware of a unifying method to do so.

PS: From what I understand of the documentation, RespectingRuntimeTypes() only affects the way members are picked when dealing with inheritance.

Upvotes: 1

Related Questions