When working with Domain Objects, how do you typically unit test a method that calls another method in the object? For example:
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;
}
}
Unit testing GetTotalAmt() is easy, but with GetExtendedTotalAmt() I'd have to use stub/mock InvoiceLine objects to make it work, when all I really want to do is test that a discount is applied if the IsDiscounted flag is true.
How do other people handle this? I don't think it makes sense to split up the domain object since these methods are both considered part of the core Invoice functionality (and splitting it would likely cause developers to call the wrong method more often).
Thanks!
You could make the GetTotalAmt
method virtual
and then:
var sut = new MockRepository().PartialMock<Invoice>();
sut.Expect(x => x.GetTotalAmt()).Return(10);
sut.Replay();
var result = sut.GetExtendedTotalAmt();
I would build up a situation which is as simple as possible: only one InvoiceLine
with a Quantity and Price of 1.
Something like this:
invoice.Add(new InvoiceLine(new Article("blah", 1M), 1));
Assert.AreEqual(0.95M, invoice.GetExtendedTotalAmt());
When you find that this stuff gets quite complicated, finding errors gets hard etc, then it is a sign that you should split the class (making the calculations on the invoice a strategy or something similar). But as long as it is as simple as you piece of code here, I wouldn't worry about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With