Moq Params TargetParameterCountException: исключение несоответствия количества параметров - PullRequest
11 голосов
/ 14 сентября 2011

Ниже приведен мой базовый базовый интерфейс хранилища

public interface IRepository<T>
{
    IQueryable<T> AllIncluding(params Expression<Func<T, 
                               object>>[] includeProperties);
}

моя сущность

public class Sdk 
{
    public Sdk()
    {
       this.Identifier = Guid.NewGuid().ToString();
    }

    public virtual ICollection<Resource> AccessibleResources { get; set; }

    public string Identifier { get; set; }    
}

и далее - конкретный репо

public interface ISdkRepository : IRepository<Sdk>
{
}

сейчас я пытаюсь протестировать контроллер, используя moq

Ниже приведен код, который я пытаюсь проверить

public ActionResult GetResources(string clientId) {
        var sdkObject = sdkRepository
                           .AllIncluding(k => k.AccessibleResources)
                           .SingleOrDefault(k => k.Identifier == clientId);
        if (sdkObject == null)
            throw new ApplicationException("Sdk Not Found");
        return Json(sdkObject.AccessibleResources.ToList());
    }

с использованием следующего теста

[Test]
public void Can_Get_GetResources()
{
    var cid = Guid.NewGuid().ToString();
    var mockRepo = new Moq.Mock<ISdkRepository>();
    var sdks = new HashSet<Sdk>()
    {
        new Sdk()
        {
            Identifier = cid,
            AccessibleResources = new HashSet<Resource>()
            {
                new Resource()
                {
                    Id = Guid.NewGuid(),
                    Description = "This is sdk"
                }
            }
        }
    };
    mockRepo.Setup(k => k.
        AllIncluding(It.IsAny<Expression<Func<Sdk,object>>[]>()))
                       .Returns(sdks.AsQueryable);
    var sdkCtrl = new SdksController(mockRepo.Object);
    var returnedJson=sdkCtrl.GetResources(cid);
    returnedJson.ToString();
}

и он бросает:

System.Reflection.TargetParameterCountException: несоответствие количества параметров

Не знаю почему?

Ответы [ 4 ]

29 голосов
/ 14 марта 2012

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

Вместо

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>()))
                     .Returns(sdks.AsQueryable);

, пожалуйста, используйте

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>()))
                     .Returns((Expression<Func<Sdk, 
                        object>>[] includeProperties) => sdks.AsQueryable());
7 голосов
/ 21 ноября 2013

Другим решением для решения этой проблемы является использование: .AsQueryable() вместо .AsQueryable.

5 голосов
/ 15 сентября 2011

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

Кроме того, я не могу вспомнить, насколько хорошо Moq обрабатывает params xx [], но это вполне возможноу вас есть комбинация из двух проблем:

Можете ли вы создать класс, который представляет набор выражений как свойство?Если это так, можно изменить сигнатуру AllIncключение и указать Moq на совпадение с любым экземпляром этого класса.

Обновление

На момент ответаограничение, но теперь возможно.Смотрите ответ Александра Литвина

2 голосов
/ 22 февраля 2017

Для других людей, ищущих ответ на этот вопрос, для меня решение добавляло то же количество параметров в Setup, что и в выражении в Returns.

Например:

Не работает с другим количеством аргументов

mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
                .Returns((string s) => s.ToLower());

Работа с тем же количеством аргументов в выражении в Returns, что и в Setup

mock.Setup(x => x.DoSomething(It.IsAny<string>()))
                .Returns((string s1, string s2) => s1.ToLower());
...