2010-05-26 2 views
18

У меня возникли проблемы с определением, как установить indexers в C# с помощью Moq. Документация Moq слаба, и я сделал много поиска ... то, что я хотел бы сделать, это аналогично в растворе How to Moq Setting an Indexed property:Использование Moq для установки индексаторов в C#

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

Я хочу изменить выше, чтобы работать для любого индекс и любое значение, так что я могу просто сделать что-то вроде этого:

someClass.Object.SomeIndexedProperty[1] = 5; 

в настоящее время у меня есть следующие, который отлично работает для геттера индексируемой собственности, но если я когда-либо установить значение Moq игнорирует:

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

Что такое индексная переменная? Откуда он? – Grzenio

+0

Я новичок в Moq, так что, возможно, я что-то делаю неправильно ... но я думал, что параметр index в лямбда Returns был предоставлен It.IsAny () выражение в настройке лямбда. –

+0

Я тоже не эксперт (я использую RhinoMocks). Does someClass.Object.SomeIndexedProperty [3] возвращает 40? – Grzenio

ответ

11

Я нашел решение моей проблемы. Это требует сдвига в моем мышлении ... Я искал, чтобы использовать NNnit's Assert, чтобы проверить, что установщик индексатора в моем макете someClass вызывается с правильным значением.

Кажется, что с помощью Moq поддерживаемый способ сделать это - использовать функцию VerifySet. Надуманный пример:

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

Блок проходит с SomeIndexedProperty[3] устанавливается на 25, но потерпит неудачу в противном случае.

+0

У меня такая же проблема, только мое индексированное свойство только для чтения, то есть у него есть только 'get' accessor. Любые идеи о том, как я могу издеваться над этим? – MoonKnight

3

В вашем тесте ваши единственные установленные ожидания для получателя индексатора - и это всегда будет возвращать соответствующее значение из вашего массива. Индексатор не ведет себя как настоящая вещь. Вы можете попробовать несколько вещей, чтобы исправить это:

  1. Вы можете проверить, не можете ли вы заглушить этот указатель. Я лично с помощью RhinoMocks, так что я понятия не имею, если это реализовано

    someClass.SetupProperty(f => f.SomeIndexedProperty); 
    
  2. Вы можете попробовать поиздеваться сеттера, а также и сделать это, чтобы изменить основной массив. Моя первая догадка бы попробовать что-то вдоль этих линий (никакой гарантии, что будет работать):

    someClass.Setup(o => o.SomeIndexedProperty[It.IsAny<int>()] = It.IsAny<int>()) 
    .Callback((index, value) => someValues[index] = value); 
    
  3. Или, если интерфейс ISomeClass достаточно мал, вы могли бы просто создали реализацию заглушки самостоятельно (что будет иметь индексацию реализован в виде словаря, массив и т.д.)

 

+0

# 1 не работал в моих экспериментах. Я пытался сделать что-то вроде # 2, но я не пробовал обратный вызов. Также спасибо за указание №3 - иногда вы пытаетесь забить винт вместо того, чтобы просто найти отвертку. –

5

Использование MOq 3.1.416.3

установки не будет работать для индексаторами (потому что он принимает выражение, которое означает, что операторы присваивания исключаются)

так что вам нужно использовать SetupSet как

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

Небольшое оговорка: Это выражение подходит только в том случае, если ключ является «MruNotes». Я не смог использовать такой помощник, как It.IsAny для ключа.

Смежные вопросы