2

1.有没有一种简单的方法可以使用 AutoFixture 中的 SemanticComparison 比较两种匿名类型?我当前的问题是我无法为第二个匿名对象构造 Likeness。简化示例:

var srcAnon = new { time = expectedTime, data = docsArray };
var resultAnon = new { time=actualTime, data = sutResponseArray };

var expectedAlike = srcAnon.AsSource()
            .OfLikeness<??WhatsHere??>()

2.我认为这个问题与第一个问题非常相关,因为它们都使用 SemanticComparison 来创建IEquatable实现。 在这个问题中,Mark Seemann 提供了一个关于如何使用 MSTest 断言和 LINQSequenceEqual方法的答案。

这可以在类似的场景中使用 XUnit2 断言库吗?XUnit支持Assert.Equal()相同类型的集合,是否可以用于不同类型的集合,但是如果元素实现了IEquatable(使用Likeness)。像这样的东西(这不起作用result并且allLikeness有不同的类型):

Assert.Equal(allLikeness.ToArray(),result.ToArray());
4

1 回答 1

4

独立于任何单元测试框架,您始终可以下拉到也需要 comparerSequenceEquals<object>重载。这将使您能够比较完全不同的列表。该测试演示了如何“欺骗” .NET 使其“认为”两个异构数组是相同的:

[Fact]
public void TestDisparateSequences()
{
    var ints = new[] { 1, 3, 5, 7 };
    var strings = new[] { "foo", "bar", "baz", "qux" };

    Assert.True(
        ints.Cast<object>().SequenceEqual(
            strings.Cast<object>(),
            new TrueComparer<object>()),
        "Arrays look like they are equal.");
}

private class TrueComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        return true;
    }

    public int GetHashCode(T obj)
    {
        return 0;
    }
}

此测试通过,因为TrueComparer始终返回 true。

显然,这不是特别实用,但它指出了可以用来比较异质序列的相关构建块。

SemantiComparison 提供了一个SemanticComparer<T>实现 的类IEqualityComparer<T>,但它只适用于相同类型的值。因此,为了使用它来比较异构序列,您需要将其中一个列表映射到另一种类型的序列中。

通常,您周围已经有这样的地图,但如果没有,这是构建地图的良好动力。否则,您可以使用像AutoMapper这样的语义映射器。

假设,作为一个例子,你有一个这样的Foo类:

public class Foo
{
    public int Number { get; set; }

    public string Text { get; set; }
}

和另一个Bar类,非常相似:

public class Bar
{
    public int Number { get; set; }

    public string Text { get; set; }
}

您现在可以使用地图和 比较 foos 和 bar SemanticComparison<Bar>

[Fact]
public void TestEquivalentSequences()
{
    var foos = new[]
    {
        new Foo { Number = 42, Text = "ploeh" },
        new Foo { Number = 1337, Text = "fnaah" }
    };
    var bars = new[]
    {
        new Bar { Number = 42, Text = "ploeh" },
        new Bar { Number = 1337, Text = "fnaah" }
    };

    AutoMapper.Mapper.CreateMap<Foo, Bar>();

    Assert.True(
        foos.Select(AutoMapper.Mapper.Map<Bar>).SequenceEqual(
            bars,
            new SemanticComparer<Bar>()),
        "Mapped arrays should be equivalent.");
}

尽管如此,如果你给你的对象Structural Equality,它会让你的生活变得更轻松。这个答案只勾勒出什么是可能的,而不是推荐什么。

于 2015-10-02T12:11:58.120 回答