I have a design problem that I can’t figure out. Here’s what I’ve got:
In general, I have two general types of objects Strikes and Options. These have been abstracted into two interfaces IStrike and IOption.
Let’s say that IOption has the following fields, in reality there are about 10 times as many, but we can use the following three to illustrate the problem.
interface IOption
{
double Bid{get;set;}
double Ask{get;set;}
double ImpliedVol{get;set;}
}
interface IStrike
{
IOption Call{get;set;}
IOption Put{get;set;}
}
Now, that’s all well and good, but let’s say I’ve got the following method for performing some “math” on the IOption implied vol
public double SquareImpliedVol(IOption opt)
{
return Math.Pow(opt.ImpliedVol,2);
}
Again, not a problem, but when I’m writing some mock objects for my tests, it’s not clear to me if I need to implement Bid and Ask. I don’t, but I wouldn’t know that unless I knew the guts inside SquareImpliedVol, which means I’m writing tests against the code, which is bad.
So to fix this, I could create another interface IOptionImpliedVol that just contains the ImpliedVol property, and then have IOption inherit from IOptionImpliedVol like so
interface IOption : IOptionImpliedVol
{
double Bid{get;set;}
double Ask{get;set;}
}
And then we can switch up SquareImpliedVol
public double SquareImpliedVol(IOptionImpliedVol opt)
{
return Math.Pow(opt.ImpliedVol,2);
}
And we’re great. I can write mock objects and everything is sweet. Except….I want to write a method that is going to operate on a List, but the only properties I need out of IStrike are the Call.ImpliedVol and Put.ImpliedVol. I want to create something like
interface IStrikeImpliedVol
{
IOptionImpliedVol Call;
IOptionImpliedVol Put;
}
and then I could also have
interface IStrike : IStrikeImpliedVol
{
IOption Call;
IOption Put;
}
Except that isn’t legal. I feel like there has to be some kind of design pattern that I could to work this out, but I’m stuck in some kind of web of composition and inheritance.
I think you’re initial design with two interfaces was correct. You’re saying that you have to know when to set
Bid/Askand when not to set it in your tests and that bothers you.Let’s try to look at it from other point. You’re writing a test for some function (let’s say it is your
SquareImpliedVolagain). You know that correctly implemented this function should care only aboutImpliedVolproperty, but not aboutBid/Askso you can leave those blank. If function will fail with unsetBid/Askthen your unit-test found an issue – be happy. Of course it differs if emptyBid/Askis incorrect state ofOptionobject, but that doesn’t seem to be an issue in your case.In other words I would say you’re writing a test against your knowledge on how particular method should work and there is nothing wrong in the fact that this knowledge correlates with code already written in that function.