I am a TDD newb and I would like to figure out how to test the following code.
I am trying to write my tests first, but I am having trou开发者_开发百科ble for creating a test that touches my DataAccessor. I can't figure out how to fake it. I've done the extend the shipment class and override the Load() method; to continue testing the object. I feel as though I end up unit testing my Mock objects/stubs and not my real objects. I thought in TDD the unit tests were supposed to hit ALL of the methods on the object; however I can never seem to test that Load() code only the overriden Mock Load
My tests were write an object that contains a list of orders based off of shipment number.
I have an object that loads itself from the database.
public class Shipment
{
//member variables
protected List<string> _listOfOrders = new List<string>();
protected string _id = ""
//public properties
public List<string> ListOrders
{
get{ return _listOfOrders; }
}
public Shipment(string id)
{
_id = id;
Load();
}
//PROBLEM METHOD
// whenever I write code that needs this Shipment object, this method tries
// to hit the DB and fubars my tests
// the only way to get around is to have all my tests run on a fake Shipment object.
protected void Load()
{
_listOfOrders = DataAccessor.GetOrders(_id);
}
}
I create my fake shipment class to test the rest of the classes methods .I can't ever test the Real load method without having an actual DB connection
public class FakeShipment : Shipment
{
protected new void Load()
{
_listOfOrders = new List<string>();
}
}
Any thoughts? Please advise.
Dave
I'm assuming DataAccessor is currently a static class.
The first step would be to create an abstraction for the DataAccessor by creating an interface.
IDataAccessor
Then you have two options, make IDataAccessor a constructor dependency see below:
public class Shipment
{
private readonly IDataAccessor dataAccessor;
public Shipment(IDataAccessor dataAccessor)
{
this.dataAccessor = dataAccessor;
}
}
Or use the Double Dispatch method shown below:
public void Load(IDataAccessor dataAccessor)
{
_listOfOrders = dataAccessor.GetOrders(_id);
}
Then in your Unit Tests you would use a stub implementation for the IDataAccessor.
make it
public Shipment(DataAccessor da, string id)
{
_da = da;
_id = id;
Load();
}
protected void Load()
{
_listOfOrders = _da.GetOrders(_id);
}
DataAccessor
should be probably be an interface.
btw, those protected data members smell like rotten fish.
精彩评论