2013-05-08 4 views
0

Я пытаюсь высмеять IDataRecord используя Moq.Как насмехаться с IDataRecord?

Макет был создан следующим образом:

Mock<IDataRecord> mockDataRecord = new Mock<IDataRecord>(); 

Линия тестируемый:

DateTime timestamp = dataRecord.GetValueOrDefault<DateTime>("QUEUE_ADD_TS"); 

Пытались:

mockDataRecord.Setup(r => r.GetValueOrDefault<DateTime>("QUEUE_ADD_TS")).Returns(now); 

... но он дает ошибку во время выполнения :

Expression references a method that does not belong to the mocked object: r => r.GetValueOrDefault("QUEUE_ADD_TS")

Также попытался заменить It.IsAny<String>() вместо "QUEUE_ADD_TS", но это не имело значения. Это должно быть легко, но я почесываю голову - благодарю за любой совет!

+2

Я не вижу '' GetValueOrDefault метода на 'интерфейса IDataRecord'. Разве это не метод расширения? –

+1

Довольно уверен, что это так, как показывает ошибка. GetValueOrDefault - это метод расширения, поэтому его нельзя напрямую обрезать. Попробуйте вместо этого наложить указатель, я уверен, что примеры будут на SO где-то :) – gaz

+0

А вы оба правы! Оказывается, «GetValueOrDefault» является методом расширения и является «статическим», поэтому его нелегко высмеять. Не уверен, как это работает, но изучая его ... –

ответ

0

Вы не можете издеваться над статическими или расширенными методами, поскольку большинство из насмешливых фреймворков используют динамические прокси под капотом.

В вашем тесте не забудьте заглушить метод расширения. Вместо заглушку самого оригинального метода, как:

mockDataRecord.Setup(r => r.GetValue<DateTime>("QUEUE_ADD_TS")).Returns(now); 

Вы должны проверить метод расширения отдельно, как:

  1. Сто метод GetValue и утверждая, что GetValueOrDefault возвращает значение погасили.

  2. Donot stub GetValue метод и утверждать, что GetValueOrDefault возвращает значение по умолчанию.

+0

Это действительно то, что я сейчас делаю - на самом деле до сих пор не встречались методы расширения! (Я не знаю, вы уходите от C# в течение нескольких лет назад, и ворота поставили ;-)). Моя единственная проблема заключается в том, что есть * много * методов установки, и общий консенсус по StackOverflow заключается в том, что каждая Setup() должна быть сопоставлена ​​эквивалентной Verify(). Кажется, излишний и сделает код более сложным в обслуживании - действительно ли мне нужно это сделать или я мог бы уйти с Verifiable() вместо этого? –

+0

VerifyAll() кажется лучше, чем спаривание каждой установки() с помощью Verify(). Очевидно, что это следует делать в каждом конкретном случае. Вы бы были лучшим судьей для этого :-) – aquaraga

+0

Я сделал то, что было сказано abve, что-то вроде этого: this.dataRecord.Setup (d => d.GetValue («WorkItemId»)). Возвращает (1); но я получил объектную референтность не для экземпляра объекта .... что я сделал не так? Кажется, что у меня такое же, как в комментарии. –

0

Я делаю это так, быстро и грязно:

Mock<IDataRecord> dataRecord = new Mock<IDataRecord>(); 
Setup(column => column["applicationno"]).Returns("foobar"); 
Setup(column => column["numberOfApplications"]).Returns(12); 
Смежные вопросы