При работе с Объектами области, как обычно делают Вас модульный тест метод, который называет другой метод в объекте? Например:
public class Invoice
{
public IList<InvoiceLine> InvoiceLines;
public string Company;
public bool IsDiscounted;
public DateTime InvoiceDate;
//...
public GetTotalAmt();
public GetExtendedTotalAmt();
public decimal GetTotalAmt()
{
decimal total;
foreach (InvoiceLine il in InvoiceLines)
{
total += il.Qty * il.Price;
}
return total;
}
public decimal GetExtendedTotalAmt()
{
decimal discount;
if (IsDiscounted)
discount = .05M;
return GetTotalAmt() * discount;
}
}
Поблочное тестирование GetTotalAmt () легок, но с GetExtendedTotalAmt () я должен был бы использовать тупиковые/ложные объекты InvoiceLine заставить его работать, когда все я действительно хочу сделать, протестировать это, скидка применяется, если флаг IsDiscounted верен.
Как другие люди обрабатывают это? Я не думаю, что имеет смысл разделять объект области, так как эти методы и рассматривают, часть базовой функциональности Счета (и разделение его, вероятно, заставило бы разработчиков называть неправильный метод чаще).
Спасибо!
Я бы выстроил ситуацию, которая максимально проста: только одна InvoiceLine
с Количеством и Ценой 1.
Что-то вроде этого:
invoice.Add(new InvoiceLine(new Article("blah", 1M), 1));
Assert.AreEqual(0.95M, invoice.GetExtendedTotalAmt());
Когда вы обнаружите, что эта штука становится довольно сложной, найти ошибки становится сложно и т.д., то это признак того, что вы должны разделить класс (сделать вычисления по счету-фактуре стратегией или чем-то подобным). Но пока он такой же простой, как и ваш код, я бы не стал об этом беспокоиться.
Вы можете сделать методом GetTotalamt
виртуальный
, а затем:
var sut = new MockRepository().PartialMock<Invoice>();
sut.Expect(x => x.GetTotalAmt()).Return(10);
sut.Replay();
var result = sut.GetExtendedTotalAmt();