2008-08-07 38 views
5

Thảm họa mới nhất của tôi vấp ngã thông qua chế nhạo không phải là grokking mà tôi cần phải thực sự đẩy kết quả bên trong một đối tượng giả của IEnumerable<T>.Làm thế nào để bạn giả lập một số IE2umerIEnumerable?

Dưới đây là một ví dụ (trình diễn duy nhất của IEnumerable<T>, không thực sự tốt thử nghiệm tương tác dựa trên!):

using System; 
using System.Collections.Generic; 
using Rhino.Mocks; 
using MbUnit.Framework; 

[TestFixture] 
public class ZooTest 
{ 
    [Test] 
    public void ZooCagesAnimals() 
    { 
     MockRepository mockery = new MockRepository(); 

     IZoo zoo = new Zoo(); 

     // This is the part that feels wrong to create. 
     IList<IAnimal> mockResults = mockery.DynamicMock<IList<IAnimal>>(); 
     IAnimal mockLion = mockery.DynamicMock<IAnimal>(); 
     IAnimal mockRhino = mockery.DynamicMock<IAnimal>(); 

     using (mockery.Record()) 
     { 
      Expect.Call(zoo.Animals) 
       .Return(mockResults) 
       .Repeat.Once(); 
     } 

     using (mockery.Playback()) 
     { 
      zoo.CageThe(mockLion); 
      zoo.CageThe(mockRhino); 

      Assert.AreEqual(mockResults, new List<IAnimal>(zoo.Animals)); 
     }  
    } 
} 


public class Zoo : IZoo 
{ 
    private IList<IAnimal> animals = new List<IAnimal>(); 

    public void CageThe(IAnimal animal) 
    { 
     animals.Add(animal); 
    } 

    public IEnumerable<IAnimal> Animals 
    { 
     get 
     { 
      foreach(IAnimal animal in animals) 
      { 
       yield return animal; 
      } 
     } 
    } 
} 

public interface IAnimal 
{ 
} 

public interface IZoo 
{ 
    IEnumerable<IAnimal> Animals { get;} 
    void CageThe(IAnimal animal); 
} 

tôi không thích làm thế nào tôi đã nhận nó để làm việc vì những lý do sau đây:

  • Tiêu thụ các kết quả IEnumerable<IAnimal> thành IList<IAnimal> - bởi vì tôi hiểu điều này đặt kết quả để kiểm tra vùng heap.
  • Thiết lập nội dung của kết quả - mà tôi cũng hiểu; nhưng điểm chính của tôi là kiểm tra rằng Zoo.Animals đang trả lại IEnumerable<IAnimal> và thậm chí tốt hơn, rằng nó đang sử dụng yield return bên trong.

Bất kỳ đề xuất nào để làm điều này tốt hơn hoặc đơn giản hơn?

Chỉnh sửa: Tôi đang cố gắng xác định cách tối ưu để kiểm tra tương tác giữa IEnumerable<T> và bất kỳ điều gì tôi đang sử dụng. Tôi không cố gắng kiểm tra rằng Zoo có thể giữ động vật, thay vì đó Zoo cho thấy là IEnumerable<IAnimal> và rằng yield return cũng đang được sử dụng.

+1

Nhìn lại, đây là câu hỏi ** TERRIBLE **. Đang cố gắng để có được phiếu để Đóng –

Trả lời

4

Nếu bạn đang thử nghiệm triển khai , tại sao bạn lại cố gắng thử nghiệm nó ngay từ đầu? Tại sao không chỉ CageThe (IAnimal) và sau đó kiểm tra xem động vật có chứa IAnimal?

Tôi hiểu rằng bạn đang chế nhạo những người IAnimals, nhưng dường như bạn không có bất kỳ động vật cụ thể nào để chơi, nhưng tại sao không chỉ làm cho họ khai, bởi vì rõ ràng bạn không mong đợi bất cứ điều gì khác xảy ra họ ngoài việc được đưa vào danh sách?

Edit: Một cái gì đó đại khái cùng những dòng này (không được thử nghiệm, có thể không biên dịch, có thể ăn thịt chó, vv của bạn):

[TestFixture] 
public class ZooTest 
{ 
    [Test] 
    public void ZooCagesAnimals() 
    { 
     MockRepository mockery = new MockRepository(); 

     IAnimal mockLion = mockery.Stub<IAnimal>(); 
     IAnimal mockRhino = mockery.Stub<IAnimal>(); 

     IZoo zoo = new Zoo(); 

     zoo.CageThe(mockLion); 
     zoo.CageThe(mockRhino); 

     List<IAnimal> animals = new List<IAnimal>(zoo.Animals); 
     Assert.IsTrue(animals.Contains(mockLion)); 
     Assert.IsTrue(animals.Contains(mockRhino)); 
    } 
} 
3

Tôi hoàn toàn không thấy làm thế nào bạn mong đợi để thiết lập những kỳ vọng giả trên một đối tượng không phải là mô hình để bắt đầu. Ngoài ra, bạn đang thiết lập kỳ vọng trả về một IList không thực sự xảy ra khi trình biên dịch tạo ra một trình lặp.

Nếu bạn muốn đặc biệt kiểm tra iterator, bạn nên có lẽ

Assert.IsNotNull(zoo.Animals); 

Và sau đó xác minh rằng các điều tra viên thực sự liệt kê trên tất cả những điều bạn đã thêm vào vườn thú. Đó là những gì tôi đã đi cho có. :)

Tôi không chắc chắn nếu nó thậm chí có thể kiểm tra nếu lợi nhuận được gọi là, vì lợi nhuận là chỉ cú pháp đường cho một trình biên dịch tạo ra IEnumerable. Ví dụ: gọi

zoo.Animals.GetEnumerator(); 

sẽ không thực thi bất kỳ mã nào bạn đã viết trong điều tra viên. Lần đầu tiên xảy ra là trên cuộc gọi đầu tiên tới IEnumerator.MoveNext();

Bây giờ, nếu bạn đang cố gắng kiểm tra tương tác giữa Sở thú cụ thể và IEnumerable được sở hữu bởi Sở thú đó, bạn nên tạo trường IEnumerable trên Sở thú và chèn một mô hình IEnumerable vào trường đó thay vì triển khai IEnumerable cụ thể trực tiếp trong Zoo.

Tôi hy vọng đây là một số trợ giúp.

Các vấn đề liên quan