Get faster with FitNesse
This is the third article in a series beginning with Busting the great TDD myth and Keep your code ignorant and lazy. If you haven’t already read these articles I recommend checking them out as I will continue to use the same code as an example.
In the last article we looked at using the Provider pattern to make a flexible data access layer. It allowed us to test our TUserRepository in isolation even though it is dependent on data. Lets breifly review that code:
type ILoadable = interface procedure AddRecord(const UserName, Password : string); end; ILoader = interface procedure Load(Target : ILoadable); end; TUserRepository = class(TInterfacedObject, ILoadable) private FUsers : TStringList; protected procedure AddRecord(const UserName, Password : string); public constructor Create(Loader : ILoader); destructor Destroy; override; function Lookup(const UserName : string) : TUser; end; TTestData = class(TInterfacedObject, ILoader) protected procedure Load(Target : ILoadable); end;
By having TUserRepository implement ILoadable and creating a stub for loading test data called TTestData we were able to write a test like this:
procedure TUserRepositoryTests.SetUp; begin TestData := TTestData.Create; FRepo := TUserRepository.Create(TestData); end; procedure TUserRepositoryTests.TestValidLookup; var user : TUser; begin user := FRepo.Lookup('fred'); CheckEquals('flinstone', user.password); end;
What’s good about this arrangement is that we’ve tested the business logic of TUserRepository independent of a data source. However we’re left the question of how to write and test the actual production code that will provide live data to TUserRepository. We could test-drive this code in a unit test but the rules of TDD tell us that a test should not need external dependencies. Also, accessing a database in a unit test would slow down the test suite. So how do we test this code?
Recent Comments