2010-05-26 11 views
18

Tôi đang gặp sự cố khi tìm ra cách đặt indexers trong C# bằng Moq. Các tài liệu Moq là yếu, và tôi đã làm rất nhiều công tìm kiếm ... những gì tôi muốn làm là tương tự như trong các giải pháp để How to Moq Setting an Indexed property:Sử dụng Moq để đặt người lập chỉ mục trong C#

var someClass = new Mock<ISomeClass>(); 
someClass.SetupSet(o => o.SomeIndexedProperty[3] = 25); 

Tôi muốn thay đổi ở trên để làm việc cho bất kỳ chỉ số và bất kỳ giá trị vì vậy tôi chỉ có thể làm một cái gì đó như thế này:

someClass.Object.SomeIndexedProperty[1] = 5; 

Hiện nay tôi có những điều sau đây, mà làm việc tuyệt vời cho các getter tài sản được lập chỉ mục, nhưng nếu tôi đã từng thiết lập giá trị Moq bỏ qua nó:

var someValues = new int[] { 10, 20, 30, 40 }; 
var someClass = new Mock<ISomeClass>(); 
someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()]) 
    .Returns<int>(index => someValues[index]); 

// Moq doesn't set the value below, so the Assert fails! 
someClass.Object.SomeIndexedProperty[3] = 25; 
Assert.AreEqual(25, someClass.Object.SomeIndexedProperty[3]); 
+0

Biến chỉ mục là gì? Nó từ đâu tới? – Grzenio

+0

Tôi mới làm quen với Moq vì vậy có lẽ tôi đang làm điều gì đó sai ... nhưng tôi nghĩ rằng tham số chỉ mục trong lambda Returns được cung cấp bởi nó.Biểu thức IsAny () trong lambda Cài đặt. –

+0

Tôi cũng không phải là chuyên gia (tôi đang sử dụng RhinoMocks). Liệu someClass.Object.SomeIndexedProperty [3] có trả về 40 không? – Grzenio

Trả lời

11

tôi tìm thấy một giải pháp cho vấn đề của tôi. Nó đòi hỏi một sự thay đổi trong suy nghĩ của tôi ... Tôi đã được tìm cách sử dụng NUnit của Assert để xác minh rằng các lập chỉ mục trong set someClass của tôi đã được gọi với giá trị chính xác.

Dường như với Moq cách được hỗ trợ để thực hiện việc này là sử dụng chức năng VerifySet. Một ví dụ giả tạo:

someClass.Object.SomeIndexedProperty[3] = 25; 
someClass.VerifySet(mock => mock.SomeIndexedProperty[3] = 25); 

Kiểm tra đơn vị vượt qua kể từ SomeIndexedProperty[3] được đặt thành 25, nhưng sẽ không thành công.

+0

Tôi có cùng một vấn đề, chỉ thuộc tính được lập chỉ mục của tôi là chỉ đọc, đó là nó chỉ có một 'get' accessor. Bất kỳ ý tưởng về cách tôi có thể giả lập điều này? – MoonKnight

3

Trong thử nghiệm của bạn, bạn chỉ đặt kỳ vọng cho getter của bộ chỉ mục - và điều này sẽ luôn trả về giá trị tương ứng từ mảng của bạn. Người lập chỉ mục không hành xử như một điều thực sự. Bạn có thể thử một vài cách để khắc phục sự cố:

  1. Bạn có thể kiểm tra xem bạn có thể mở trình lập chỉ mục này không. Cá nhân tôi đang sử dụng RhinoMocks, vì vậy tôi không có ý tưởng nếu điều này được thực hiện

    someClass.SetupProperty(f => f.SomeIndexedProperty); 
    
  2. Bạn có thể thử để thử setter cũng và làm cho nó thay đổi mảng tiềm ẩn. đoán đầu tiên của tôi là để thử một cái gì đó dọc theo những dòng (không có bảo đảm nó sẽ làm việc):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>()) 
    .Callback((index, value) => someValues[index] = value); 
    
  3. Hoặc nếu giao diện ISomeClass đủ nhỏ, bạn chỉ có thể tạo ra một bài thi cho mình (mà có thể có các chỉ mục thực hiện như một cuốn từ điển, mảng, vv)

 

+0

# 1 không hoạt động trong thử nghiệm của tôi. Tôi đã cố gắng làm một cái gì đó như # 2, nhưng tôi đã không thử gọi lại. Cũng cảm ơn vì đã chỉ ra # 3 - đôi khi bạn kết thúc việc cố gắng để búa vào một ốc vít thay vì chỉ tìm kiếm một tuốc nơ vít. –

5

Sử dụng Moq 3.1.416.3

Setup sẽ không làm việc cho bộ chỉ mục (vì phải mất một biểu thức có nghĩa là câu lệnh gán được loại trừ)

vì vậy bạn cần phải sử dụng SetupSet như

_settingsStore.SetupSet(store => store["MruNotes"] = It.IsAny<string>()) 
       .Callback<string,string>((key, value) => persistedValue = value); 

Thông báo nhỏ: biểu thức này chỉ khớp nếu khóa là "MruNotes". Tôi đã không thể sử dụng một matcher như It.IsAny cho khóa.