CopyAndUpdateAssertion - I / O不匹配

时间:2015-01-09 12:37:37

标签: c# idioms autofixture

这个问题与AutoFixture的CopyAndUpdateAssertion的使用有关,可以在其成语nuget中找到。

假设有一个类似于这个的类:

public class Foo
{
    public static readonly Foo Empty = new Foo(
        new Bar1[0], 
        new Bar2[0]);

    private readonly Bar1[] _bars1;
    private readonly Bar2[] _bars2;

    public Foo(
        Bar1[] bars1,
        Bar2[] bars2)
    {
        if (bars1 == null) 
          throw new ArgumentNullException("bars1");
        if (bars2 == null) 
          throw new ArgumentNullException("bars2");

        _bars1 = bars1;
        _bars2 = bars2;
    }

    public Bar1[] Bars1
    {
        get { return _bars1; }
    }

    public Bar2[] Bars2
    {
        get { return _bars2; }
    }

    public Foo Append(Bar1 value)
    {
        if (value == null) throw new ArgumentNullException("value");
        return new Foo(
            _bars1.Concat(new[] {value}).ToArray(),
            _bars2);
    }

    public Foo Append(Bar2 value)
    {
        if (value == null) throw new ArgumentNullException("value");
        return new Foo(
            _bars1,
            _bars2.Concat(new[] { value }).ToArray());
    }

    public bool Equals(Foo other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return _bars1.SequenceEqual(other._bars1) &&
               _bars2.SequenceEqual(other._bars2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != GetType()) return false;
        return Equals((Foo)obj);
    }

    public override int GetHashCode()
    {
        return _bars1.Aggregate(0, (current, next) => current ^ next.GetHashCode()) ^
               _bars2.Aggregate(0, (current, next) => current ^ next.GetHashCode());
    }
}

是否可以使用CopyAndUpdateAssertion测试Append方法,因为输入是单值的(例如'value'),输出上的属性是多值的(例如'Bars1'属性)?如果是的话,应该更换哪些默认管道,你能提供关于我应该从哪里开始寻找的任何指示吗?

1 个答案:

答案 0 :(得分:3)

这不是CopyAndUpdateAssertion可以解决的问题,而且我不知道可以调整它以测试类似的内容。

您可以提出各种方法的变体,例如上面的Append方法:先插入而不是之后插入。附加到字符串,而不是替换它。添加到现有号码。等

这有点落在复制和更新概念之外;它是复制和更新,然后是更多内容。

显然,如果您需要诸如上述Append方法之类的方法,它们显然会增加价值,但除此之外,您还可以考虑采用更可组合的方法。

首先,为了使序列更容易附加,你可以考虑这样的扩展方法:

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T value)
{
    return source.Concat(new[] { value });
}

如果您认为Foo已经有了标准&#39; WithBars1 复制和更新方法,您可以获得与以下相同的结果:

var foo1 = foo.WithBars1(foo.Bars1.Append(someBar).ToArray());

当然,这行代码比foo1 = foo.Append(someBar)更复杂或更详细,但另一方面,它需要更少的测试覆盖率,因为它是由标准&#构建的39;积木。


最后,最终,在两三个代码库中做了类似的事情之后,这是让我转向F#的众多原因之一,其中大部分已经内置:

let foo' = { foo with Bars1 = foo.Bars1 |> Array.append [| someBar |] }

完全不需要单元测试来支持上面的表达式,因为它只使用F#语言功能和内置函数。