2013-07-04 5 views
1

У меня есть метод интерфейса, чья подпись выглядит следующим образом:Как вы выражаете ожидания относительно передачи коллекции в качестве параметра?

void SetValues(IDictionary<string, object> the_values); 

У меня есть класс клиента, использующие этот метод. Я хочу, чтобы модульный тест для этого класса проверял, что в конкретном случае передается конкретная пара ключей и значений. Прямо сейчас, если я хочу выразить, что я ожидаю, что метод SetValues будет вызываться с помощью одного ключа -value пара { "Дата", DateTime (1972,1,2)} Я пишу следующее:

item.Expect(i => i.SetValues(
      Arg<IDictionary<string, object>>.Matches(
       (items) => (items.Count() == 1 && 
        items.First().Key == "Date" && 
        (DateTime) items.First().Value == new DateTime(1972,1,2)))); 

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

ответ

1

Скорее всего нет. Я согласен, что это пограничная линия уродливая. Но что еще более важно, это дает расшифровке сообщение об исключении, как это:.

IInterface.SetValues ​​(пункты => items.Count() == 1 & & items.First() Key == «Дата "& & (DateTime) items.First(). Значение == new DateTime (1972,1,2)); Ожидаемое # 1, действительное # 0.

Да, вы узнаете не удалось. Не очень полезная информация через 2 недели. По правде говоря, когда это произойдет, вам, скорее всего, придется отлаживать его, чтобы узнать, что происходит. Вместо этого я предлагаю сделать это:

item.Expect(i => i.SetValues(Arg<IDictionary<string, object>>.Is.Anything)) 
    .WhenCalled(invocation => 
    { 
     var items = invocation.Arguments 
      .OfType<IDictionary<string, object>>() 
      .First(); 
     Assert.That(items.Count(), Is.EqualTo(1)); 
     Assert.That(items.First().Key, Is.EqualTo("Date"); 
     // ... 
    }); 

Или, поставив проверки в собственный метод в целом:

item.Expect(i => i.SetValues(IsCalledWithCorrectPair())); 

// ... 

private IDictionary<string, object> IsCalledWithCorrectPair() 
{ 
    return Arg<IDictionary<string, object>>.Matches(items => 
    { 
     Assert.That(items.Count(), Is.EqualTo(1)); 
     Assert.That(items.First().Key, Is.EqualTo("Date"); 
     // ... 
     return true; 
    }); 
} 
+0

на самом деле, это близко к тому, что я в конечном итоге писать. Теперь у меня есть метод утилиты, который выполняет проверку содержимого словаря для произвольного количества пар ключ-значение, вызываемых с помощью метода расширения Rhino.Mocks .Do(). –

0

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

items.Count() == 1 && items["Date"]== new DateTime(1972,1,2); 

Вы также можете использовать сравнение сбора, как покрыты Comparing two collections for equality irrespective of the order of items in them.