2013-01-24 55 views
6
驗證可枚舉列表

我試圖寫它看起來像這樣的方法的單元測試:中起訂量

public int Save(IEnumerable<int> addedIds, IEnumerable<int> removedIds) 
{ 
    var existingIds = repository.Get(); 
    IEnumerable<int> ids = existingIds.Except(removedIds).Union(addedIds)); 
    return repository.Create(ids); 
} 

中起訂量的測試看起來是這樣的:

repository.Setup(r => r.Get()).Returns(CreateList()); 
service.Save(addedIds, removedIds); 
repository.Verify(r => r.Create(It.Is<IEnumerable<int>>(l => VerifyList(l)))); 

這種失敗與此錯誤,並VerifyList()不會被調用:

上模擬

預計調用至少一次,但從來沒有 進行:

r => r.Create(It.Is<IEnumerable'1>(list => VerifyList(list)))

演出調用:

IRepo.Create(System.Linq.Enumerable+<UnionIterator>d__88'1[System.Int32])

,作爲調用類型不是IEnumerable<int>但實際上System.Linq.Enumerable+<UnionIterator>d__88'1[System.Int32]),測試失敗。 (通過測試步進,一切正常發生的事情,結果如預期)

如果我在測試中的方法調用ids.ToList(),這些都是結果:在模擬

預計調用至少一次,但從未進行:

r => r.Create(It.Is<List'1>(l => VerifyList(l)))

演出調用: IRepo.Create(System.Collections.Generic.List'1[System.Int32])

這有什麼辦法嗎?或者我做錯了什麼?

編輯:事實證明,我在我的VerifyList方法中有一個錯誤,所以它返回false,但Moq沒有給我這些信息。該類型的差異是一個紅色的鯡魚..

回答

8

這似乎是工作。儘管做了一些假設。猜測VerifyList方法可能會更好。 =)

[Test] 
    public void Test() 
    { 
     // SETUP 
     Mock<IRepository> repository = new Mock<IRepository>(); 
     Service service = new Service(repository.Object); 
     repository.Setup(r => r.Get()).Returns(CreateList()); 

     IEnumerable<int> addedIds = new[]{1,2}; 
     IEnumerable<int> removedIds = new[]{3,4}; 
     service.Save(addedIds, removedIds); 

     repository.Verify(r => r.Create(It.Is<IEnumerable<int>>(l => VerifyList(l)))); 
    } 

    private static bool VerifyList(IEnumerable<int> enumerable) 
    { 
     return enumerable.Contains(1) && enumerable.Contains(2) && enumerable.Contains(5); 
    } 

    private IEnumerable<int> CreateList() 
    { 
     return new[] { 3, 4, 5 }; 
    } 

    public interface IRepository 
    { 
     IEnumerable<int> Get(); 
     int Create(IEnumerable<int> id); 
    } 
    public class Service 
    { 
     public Service(IRepository repository) 
     { 
      this.repository = repository; 
     } 

     private IRepository repository; 

     public int Save(IEnumerable<int> addedIds, IEnumerable<int> removedIds) 
    { 
     var existingIds = repository.Get(); 
      IEnumerable<int> ids = existingIds.Except(removedIds).Union(addedIds); 

     return repository.Create(ids); 
    } 
+0

謝謝,那個測試通過我的版本的Moq。我仍然不明白爲什麼我的失敗.. – stuartd

+0

這很奇怪。你能更新Moq嗎?你正在使用哪個版本的Moq? – Markus

+0

我在我的VerifyList方法中發生了一個錯誤,事實證明,它畢竟是被調用的。感謝您的幫助.. – stuartd

2

東西快速和骯髒 -

public interface IBlah 
{ 
    void Sum(IEnumerable<int> baz); 
} 

class Blah : IBlah 
{ 
    public void Sum(IEnumerable<int> baz) 
    { 
     return; 
    } 
} 

public class Baz 
{ 
    private readonly IBlah blah; 

    public Baz(IBlah blah) 
    { 
     this.blah = blah; 
    } 

    public void Sum(IEnumerable<int> baz) 
    { 
     blah.Sum(baz); 
    } 
} 

並測試它喜歡 -

[Test] 
public void foo() 
{ 
    var mock = new Mock<IBlah>(); 
    var enumerable = Enumerable.Range(1, 10); 

    var baz = new Baz(mock.Object); 
    baz.Sum(enumerable.Where(x => x%2 == 0)); 

    mock.Verify(p => p.Sum(It.Is<IEnumerable<int>>(z => z.All(x => x%2==0)))); 
}