Do NOT Mock System.Data.*

time to read 7 min | 1241 words

While it is possible, it is a pain in the ass. I'm working on a project now that doesn't use NHibernate (yes, I am surprised too).

There is very simple data acess there, and nearly nothing to do with touching the data, so I thought that I could simply use ADO.Net. It works, sort of, but my code is full of strings, and it is nearly untestable. The main issue is that all the *DataAdapter expect their own *Command, *Connection, etc. Which mean that I can't mock much of it.

Check out this little piece of a test (part of about 50 lines of setup, that leads to two lines of real test.

MockRepository mocks = new MockRepository();

IDbConnectionProvider connectionProvider = mocks.CreateMock<IDbConnectionProvider>();

IDbConnection connection = mocks.CreateMock<IDbConnection>();

IDbCommand getRecordsCommand = mocks.CreateMock<IDbCommand>();

ISender sender = mocks.CreateMock<ISender>();

SetupResult.For(connectionProvider.Connection).Return(connection);

IDbCommand deleteItems = mocks.CreateMock<IDbCommand>();

IDbDataParameter dataParameter = mocks.CreateMock<IDbDataParameter>();

IClock clock = mocks.CreateMock<IClock>();

SetupResult.For(clock.Current).Return(new DateTime(2006, 12, 20, 22, 45, 33));

 

connection.Open();

Expect.Call(connection.CreateCommand()).Return(getRecordsCommand);

 

string spToGetItems = "GetLockedRecords";

string spToDeleteItems = "DeleteItems";

getRecordsCommand.CommandText = spToGetItems;

getRecordsCommand.CommandType = CommandType.StoredProcedure;

getRecordsCommand.Dispose();

I could do the same with NHibernate in about three lines, and that would be easy. I'm considerring ripping what I already have and going that route. It would certainly be easier.