2011-09-22 13 views
7

Tôi đang cố gắng xác nhận rằng một phương pháp đã được gọi trên một sơ khai. Phương pháp tôi đang cố gắng khẳng định được gọi là mất IEnumerable<string>. Tôi không quan tâm đến nội dung chính xác, nhưng tôi chỉ muốn kiểm tra rằng số lượng là một số nhất định. Tôi không thể có được sự khẳng định đúng, tôi nhận đượcRàng buộc danh sách mô hình tê giác

Rhino.Mocks.Exceptions.ExpectationViolationException : Bob.DoThings(collection count equal to 10); Expected #1, Actual #0. 

Tôi biết rằng DoThings() được thực sự được gọi là ... Tôi chỉ không thể có được các hạn chế đúng ..

var myBob= MockRepository.GenerateStub<Bob>(); 
var countConstraint = Rhino.Mocks.Constraints.List.Count(Rhino.Mocks.Constraints.Is.Equal(10)); 

// execution code.... 
Joe myJoe = new Joe(myBob); 
myJoe.MethodThatShouldCallDoThingWith10(); 

myBob.AssertWasCalled(s => s.DoThings(null), o => Constraints(countConstraint)); 

tôi cũng đã thử thêm "IgnoreArguments" như một ràng buộc. Tôi đang thiếu gì?

Trả lời

11

Vấn đề ở đây là với thực thi hoãn lại. Chỉ đến khi số IEnumerable<string> được liệt kê là danh sách các mục được "xây dựng". Kể từ khi Rhino.Mocks chỉ ghi lại những gì được gọi là, nó không bao giờ "sử dụng" các đối số phương pháp và do đó, danh sách không bao giờ được xây dựng cũng không liệt kê. Như bạn đã thấy, việc thêm một ToList() hoặc ToArray() liệt kê và xây dựng danh sách để kiểm tra sẽ vượt qua nếu bạn sử dụng một trong những phương thức đó.

Một workaround là để lấy danh sách đã được thông qua với phương pháp và thực hiện kiểm tra của bạn trên rằng:

var list = (IEnumerable<int>) myBob.GetArgumentsForCallsMadeOn(b => b.DoThings(null))[0][0]; 
Assert.AreEqual(10, list.Count()); 

thử nghiệm này đi và không đòi hỏi bất kỳ thay đổi mã của bạn.

+0

Patrick, tôi không nhận thức được phương thức GetArgumentsForCallsMadeOn(). Tôi đã có thể viết một khẳng định có ý nghĩa ở đây. Các sự cố thực hiện bị trì hoãn dường như thường xuyên bị cắt xén. Cảm ơn. –

2

Sự cố này đã được báo cáo một cách alredy Here. Tôi đã có thể để tái tạo vấn đề này như sau Bob và Joe:

public interface Bob 
{ void DoThings(IEnumrable<int> list); } 

public class Joe 
{ 
    private readonly Bob bob; 

    public Joe(Bob bob) 
    { this.bob = bob; } 

    public void MethodThatShouldCallDoThingWith10() 
    { 
      var values = Enumerable.Range(1, 100).Where(x => x > 0 && x < 11); 
      bob.DoThings(values); 
    } 
} 

Có vẻ như có một số vấn đề trong Rhino Mocks sau khi tất cả, khi nói đến LINQ: hoặc báo cáo lỗi cho Ayende hoặc thêm ToList () trong mã sản xuất của bạn (không thực sự được đề xuất) ...

+0

Tôi lạ ... Nếu tôi đặt điểm ngắt trong MethodThatShouldCallDoThingWith10, tôi có thể thấy rằng thể hiện bob là proxy và đang thực hiện cuộc gọi. Rõ ràng đây không phải là mã thực sự của tôi ở đây, nhưng vâng, tôi nghĩ có một thứ gì đó không phù hợp, nhưng tôi không đặt ngón tay vào nó –

+0

Bạn có thể bắt đầu đơn giản ... Bob có phải là giao diện không? Tóm tắt lớp học? Lớp học với phương pháp ảo? –

+0

Tôi là một giao diện có chung chung ... một Bob . Tôi tự hỏi rằng các đơn vị được thử nghiệm đang gọi MethodThatShouldCallDoThingWith10 với một WhereSelectIterator , không phải cái gì cơ bản hơn như một Danh sách hoặc một đơn giản IEnumerable . Tôi nghĩ rằng một ràng buộc Count không phải là tha thứ? –