Насмешка над ленивым интерфейсом приводит к исключению во время выполнения

#c# #unit-testing #moq #.net-4.6.2

Вопрос:

У меня возникли трудности при попытке правильно имитировать произвольный интерфейс, завернутый в ленивый класс.

Я пытался:

 [TestClass] public class MyFooServiceTests {  private Mocklt;Lazylt;IFoogt;gt; _lazyFooMock = new Mocklt;Lazylt;IFoogt;gt;();  private Mocklt;IFoogt; _fooMock = new Mocklt;IFoogt;();  private MyFooService _service;   [TestMethod]  public void FooMethod_HappyPath_ShouldReturn()  {  //Arrange  _fooMock  .Setup(x =gt; x.DoSomething())  .Returns(1);   _lazyFooMock  .SetupGet(x =gt; x.Value)  .Returns(_fooMock.Object); // --------gt; Throws Exception.   _service = new MyService(_lazyFooMock.Object);  } }  public interface IFoo {  int DoSomething(); }  public class MyFooService {  public MyFooService(IFoo foo) { ... } }  

Сообщение об исключении:

Неподдерживаемое выражение: x =gt; x.Не переопределяемые члены значения (здесь: Lazy.get_Value) не могут использоваться в выражениях настройки / проверки.

Moq: 4.16.1

Комментарии:

1. Вы не можете издеваться над участниками, которые не являются виртуальными, при использовании Moq. Lazylt;Tgt;.Value не является виртуальным, следовательно, над ним нельзя насмехаться.

2. Почему ты Lazylt;Tgt; все равно пытаешься издеваться над а? Просто создайте новый Lazylt;IFoogt; , который возвращает _fooMock.Object

3. Эй, ребята, спасибо за советы, смотрите ответ

Ответ №1:

Решенный с помощью других, я сбросил _lazyFooMock и заменил его фактическим ленивым: _lazyFoo , и инициировал его с помощью перегрузки: public Lazy(Funclt;Tgt; valueFactory) .

 private Mocklt;IFoogt; _fooMock = new Mocklt;IFoogt;(); private Lazylt;IFoogt; _lazyFoo;  private MyFooService _service;  [TestMethod] public void FooMethod_HappyPath_ShouldReturn() {  //Arrange  _fooMock  .Setup(x =gt; x.DoSomething())  .Returns(1);   _lazyFoo = new Lazylt;IFoogt;(() =gt; _fooMock.Object);   _service = new MyFooService(_lazyFoo); }  

Комментарии:

1. У вас есть опечатка здесь и в вашем вопросе: Retrus lt; Returns

2. Привет @PeterCsala спасибо