2015-01-09 25 views
3

此问题涉及AutoFixture的CopyAndUpdateAssertion的使用,可在其习语nuget中找到。CopyAndUpdateAssertion - I/O不匹配

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

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,因为输入是单值的追加方法(例如在“值”)和产出的属性是多值的(例如'Bars1'属性)?如果是,应该更换哪些缺省管道,并且可以提供关于我应该从哪里开始寻找的指示?

+0

是否有可能使'Foo'成为'IBar'的迭代器?然后Concat(以及Append)将成为OOTB,成为一流的公民。 –

+0

在特殊情况下,我正在处理IBar等界面上的螺栓连接,以便在另一边(或访问者)进行铸造。无论如何,Bar1和Bar2之间几乎没有相似之处。在他们上调用的行为是不同的。我确实考虑过这个问题,但它在计算的这一方面会带来的好处让它在另一方面变得更加困难。 –

回答

3

这不是CopyAndUpdateAssertion可以解决的问题,我也不知道它可以被调整来测试这样的事情。

你可以想出各种方法的变化,如上面的Append方法:插入之前而不是之后。附加到一个字符串,而不是替换它。添加到现有号码。等

这有点落在复制并更新概念;它的复制和更新然后更多。很显然,如果你需要很多方法,比如上面的Append方法,他们显然会增加价值,但是除此之外,你也可以考虑一种更可组合的方法。

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

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

如果你想象Foo已经有一个“标准” WithBars1复制和更新方法,你可以为达到同样的效果:

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

当然,这行代码是比较复杂的,或更详细的,比foo1 = foo.Append(someBar),但另一方面,它需要更少的测试覆盖率,因为它是用“标准”构建块构建的。


不过,最终成就了类似的东西在两个或三个代码库后,这是的众多原因之一,让我转移到F#,其中大部分是已经内置:

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

根本不需要单元测试来支持上述表达式,因为它仅使用F#语言功能和内置函数。