Continuation from my 1st blog about Fake/Mock object. With the availbility of Dependency Injection framework(Microsoft Pattern and Practice ObjectBuilder, Spring Framewrok and StructureMap). We could easily swicth the implemetation of our interface. In my opinion creating a Mock just for the sake of it, just going to make your code less readable i.e. it's going to cost more on the maintanance.
This is how we would normally work when dealing with a dependency that we didn't really care about. Just as exmple we have a domain object called Patient, it has one operation , Save() returs void, the idea is when we call Save on the Patient instance, it must do some validation, then if the patientID is not null , it's new item and we want to add a new item to our persintance, if PatientID is not null, is mean we're updating existing patient.
// our test case
[Test]
public void SavePatient()
{
Patient p = new Patient();
p.Save();
Assert.AreEqual(p.PatientID, 30);
}
public class Patient
{
public int PatientID { set; get;}
public void Save()
{
if (this.Validator.Validate(this))
throw new ArgumentException("Validation error");
if (PatientID > 0)
{
this.Persistance.Update(this);
}
else
{
this.PatientID = this.Persistance.Add(this);
}
}
}So there are a couple of dependecies that we have here in order to make this method works , the Persistace and Validator, so what do we want to do is to test the domain Save method , not the Persistance or Validator. So the instinct is to do some refactoring , the first one is "Extract Interface" ( please refer to Martin Fowler -Refactoring for more refactoring details, I also a bif fan of Refactoring to Pattern by Joshue Krienvesky). Instead of having a concrete class for Validator and Persistance we now rever it to their interface
public interface IValidator
{
bool Validate(Patient patient);
}
public interface IPersistance
{
int Save(Patient patient);
}
// thus our patient object
private IValidator m_validator;
private IPersistance m_persistance;
public IPersistance Persistance
{
get { return m_persistance; }
set { m_persistance = value; }
}
public IValidator Validator
{
get { return m_validator; }
set { m_validator = value; }
}