I have a similar scenario to this:
public class VatCalculator
{
public decimal GetValueWithVat(decimal value, decimal? vatRatePercentage)
{
if(vatRate == null)
{
return value;
}
return value * (1 + (vatRate / 100));
}
}
public ReceiptGenerator
{
private readonly VatCalculator _vatCalculator;
public ReceiptGenerator(VatCalculator vatCalculator)
{
_vatCalculator = vatCalculator;
}
public Receipt GenerateReceipt(Item purchasedItem, decimal? vatRate)
{
var receipt = new Receipt();
receipt.PriceBeforeVat = purchasedItem.Price
receipt.PriceAfterVat = _vatCalculator.GetValueWithVat(purchasedItem.Price, vatRate)
}
}
In this case, I have a few unit tests I'd like to write, e.g.
- If no VAT rate is provided, the 'Price After Vat' value should be equal to the purchased item's price.
- If a VAT rate is provided, the 'Price After Vat' value should be adjusted accordingly
My question is whether I should write these unit tests at the level of the ReceiptGenerator
class or the VatCalculator
class.
If I test at the ReceiptGenerator
class level it means I have more durable tests; The code of GenerateReceipt
can be refactored e.g. to use a private method or an API and the tests should still pass with no changes. But this seems like too large of a scope for a unit test, my understanding was that it should be a very granular focused test
If I test at the VatCalculator
level I can use that class in other consumers (for example, if I move my business online, I can use it to provide on-the-go prices for customers browsing a product) without having to test the consumers themselves.