2015-01-09 18 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#語言功能和內置函數。