насмешливое поведение коллекции с Moq - PullRequest
1 голос
/ 16 июня 2010

Я прочитал некоторые дискуссии по группе пользователей Moq и не смог найти пример и до сих пор не смог найти сценарий, который у меня есть.Вот мой вопрос и код:

// 6 periods
var schedule = new List<PaymentPlanPeriod>()
{
    new PaymentPlanPeriod(1000m, args.MinDate.ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(1).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(2).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(3).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(4).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(5).ToString())
};

// Now the proxy is correct with the schedule
helper.Setup(h => h.GetPlanPeriods(It.IsAny<String>(), schedule));

Затем в моих тестах я использую Periods, но Mocked _PaymentPlanHelper никогда не заполняет коллекцию, см. Использование ниже:

public IEnumerable<PaymentPlanPeriod> Periods
{
 get
 {
  if (CanCalculateExpression())
     _PaymentPlanHelper.GetPlanPeriods(this.ToString(), _PaymentSchedule);

  return _PaymentSchedule;
 }
}

Теперь, если я изменюmocked объект для использования другого перегруженного метода GetPlanPeriods, который возвращает список следующим образом:

var schedule = new List<PaymentPlanPeriod>()
{
    new PaymentPlanPeriod(1000m, args.MinDate.ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(1).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(2).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(3).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(4).ToString()),
    new PaymentPlanPeriod(1000m, args.MinDate.Value.AddMonths(5).ToString())
};

helper.Setup(h => h.GetPlanPeriods(It.IsAny<String>())).Returns(new List<PaymentPlanPeriod>(schedule));

List<PaymentPlanPeriod> result = new _PaymentPlanHelper.GetPlanPeriods(this.ToString());

Это работает, как и ожидалось.Любые указатели будут великолепны, если вы не нарушите мою архитектуру ... :)

Спасибо, Стивен

1 Ответ

4 голосов
/ 16 июня 2010

Метод установки в основном предназначен для настройки некоторого поведения с исключениями. Например, чтобы настроить Mock-Instance для возврата определенных значений. Например, макет конфигурации:

var configMock = new Mock<IConfiguration>();
configMock.Setup(c=>c.GetSetting("Title")).Returns("Hello Word");
configMock.Setup(c=>c.GetSetting("Answer")).Returns("42");

Это означает, что когда вы передаете «Title» методу GetSetting, макет вернет «Hello Word». И когда вы передадите «Ответить» макету, он вернет «42». Кроме того, вы можете настроить подстановочные знаки. Например:

var configMock = new Mock<IConfiguration>();
configMock.Setup(c=>c.GetSetting(It.IsAny<String>())).Returns("Hello Word");

Теперь для любого вызова метода GetSetting метод mock будет возвращать строку "Hello World"

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

Afaik вы можете настроить Moq на что-то с аргументами. Как это:

helper.Setup(c => c.GetPlanPeriods(It.IsAny<string>(),It.IsAny<List<PaymentPlanPeriod>>()))
            .Callback((string s, List<PaymentPlanPeriod> l)=>
                          {
                              l.Add(new PaymentPlanPeriod(1000m, args.MinDate.ToString()));
                          });

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...