20 May 2008
Комплексна перевірка параметрів за допомогою Rhino.Mocks (Callback)
В Rhino.Mocks є достатньо цікавий функціонал для перевірки вхідних параметрів, це Callback.
Коротко це метод який приймає делегат, який виконується на час виклику. По правилам цей метод повинен повернути true якщо все добре, або false якщо навпаки.
Головна проблема це сигнатура делегату, вона повинна повертати булево значення, і приймати копію параметрів. Зрозуміло кожного разу можна писати новий делегат. Але набагато цікавіше скористатися дженериками ;).
Далі все просто, це дженеріки які нам потім знадобляться:
public delegate bool Verify<T1>(T1 obj1);
public delegate bool Verify<T1, T2>(T1 obj1, T2 obj2);
public delegate bool Verify<T1, T2, T3>(T1 obj1, T2 obj2, T3 obj3);
public delegate bool Verify<T1, T2, T3, T4>(T1 obj1, T2 obj2, T3 obj3, T4 obj4);
До речі, можна такі дженеріки і не писати, адже .Net 3.5 вже має універсальні делегати:
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
...
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
А це код який їх використовує, я до речі, тут використовую Lambda Expressions:
sourceService.UpdateItem(null, null);
LastCall.On(sourceService)
.Callback(
new Verify<SourceAnchor, DataItem>(
(anchor, item) =>
{
Assert.IsNotNull(anchor, "Anchor should not be null");
Assert.AreEqual(sourceId, anchor.SourceId, "Anchor should have predefined source ID");
Assert.AreEqual(discoveryUri, anchor.DiscoveryUri, "Anchor should have predefined URI");
// Always return true because we use assertions instead of relaying on return results
return true;
}
)
)
.Repeat.Any();
Або якщо не подобається лямбда, можна скористатися старим добрим синтаксисом:
.Callback(
new Verify<SourceAnchor, DataItem>(
delegate(SourceAnchor anchor, DataItem item) {
Assert.IsNotNull(anchor, "Anchor should not be null");
//...
return true;
}
)
)
До речі, чесно кажучи не знаю чим опікувались розробники, але повертати булево для перевірки параметрів, це дуже погана ідея. Ми самотужки викидаємо всю інформацію, стосовно того що скоїлось. Для того щоб обійти цю халепу, я і використовую асерти прямісінько в методі перевірки.
Цікавлюсь DDD. Більшість часу витрачаю на доньку. А ще вел!