Установите вызов Moq для защищенного виртуального метода, который ожидает Func и возвращает IEnumerable

1

У меня есть следующий код.

public class MyClass
{
    protected virtual IEnumerable<TResult> MyMethod<TResult>(Func<IDataReader, IEnumerable<TResult>> arg)
    {
       ....
    }
} 

Как я могу настроить метод Mock для этого?

Я пробовал, но ошибся.

using Moq;
using Moq.Protected;
namespace Foo
{
    [TestClass]
    public class TestClass
    {
        Mock<MyClass> m_mockObject = null;
        [TestMethod]
        public void MyTest()
        {
            m_mockObject = new Mock<MyClass>();
            AddMethod<Func<IDataReader, IEnumerable<SomeOtherClass>>, IEnumerable<SomeOtherClass>>(this.MyMethod);

        }

        private void AddMethod<TIn, TResult>(Func<TIn, TResult> method)
        {
             m_mockObject.Protected().Setup<TResult>(method.Method.Name, ItExpr.IsAny<TIn>())
                                                    .Returns(method); /* THIS LINE IS THROWING THE EXCEPTION */
        }

        public IEnumerable<TResult> MyMethod<TResult>(Func<IDataReader, IEnumerable<TResult>> arg)
        {
            ....
        }
    }
}

После запуска кода я получаю следующую ошибку при вызове функции Setup.

> System.ArgumentException was unhandled by user code
  HResult=-2147024809
  Message=Expression of type 'System.Object' cannot be used for return type 'System.Collections.Generic.IEnumerable'1[SomeOtherClass]'
  Source=System.Core
  StackTrace:
       at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection'1 parameters)
       at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable'1 parameters)
       at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable'1 parameters)
       at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
       at Moq.Protected.ProtectedMock'1.Setup[TResult](String methodOrPropertyName, Object[] args)
       ....
       .....
  InnerException: 
Теги:
unit-testing
moq

3 ответа

3

не знаете, почему вы возвращаете метод... но можете ли вы попробовать изменить его на:

m_mockObject.Protected().Setup<IEnumerable<TResult>>(method.Method.Name, ItExpr.IsAny<TIn>()).Returns(new List<TResult>());

Посмотрите, работает ли это.

  • 2
    Я считаю, что я нашел основную причину проблемы, Mock.Protected не делает правильную вещь при использовании отражения для методов типа Generic, следующая ссылка предоставляет более подробную информацию об основной причине их ошибки stackoverflow.com/questions/269578 /… Большое спасибо за вашу помощь.
  • 0
    Интересно, что с помощью ItExpr.IsAny<...>() вместо It.IsAny<...>() фиксированная моя проблема, и я не знаю , почему It не работает в этом сценарии.
1

myMethod1 возвращает IEnumerable<TResult>, а не делегат, как я думаю, вы ожидаете.

0

Я считаю, что я нашел основную причину проблемы, Mock.Protected не работает правильно при использовании рефлексии для методов Generic type, следующая ссылка дает более подробную информацию о корневой причине их ошибки. Get the generic method без использования GetMethods

Большое спасибо за вашу помощь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню