I am writing unit tests for my data access layer. To achieve this I have created a wrapper for SqlCommand (ISqlCommand) so that I can mock its functionality.
ISqlCommand command = _connection.GetSqlCommand(sqlCommand);
In one of the methods I am testing, SqlCommand's ExecuteReader method is being called and I have to return a SqlDataReader.
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
In this same method reader.Read will get called
if (reader.Read())
{
someVariable = reader.GetString(1);
}
What I want is to be able to return a SqlDataReader object from the mocked command.ExecuteReader() with a value present for me to Read. Can it be done? It seems that SqlDataReader can only be instantiated from an actual SqlCommand.ExecuteReader being run and returning a SqlDataReader. Full relevant code to be tested.
ISqlCommand command = _connection.GetSqlCommand(sqlCommand);
using (command)
{
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow);
if (reader.Read())
{
dbVersion = reader.GetString(1);
}
}
EDIT: To clear about what I am asking. SqlDatareader has no public constructor. As far as I can tell I cannot write any tests using that class as I cannot instantiate it without making a legitimate call to a database using SqlCommand. Even trying to create an interface of a SqlDataReaderWrapper will no help me as the problem is the same. I am not trying to write an integration test (making actual calls to a DB) and so the DataReader seems impossible to test as is. My question is, is there anything i can do, to put values into a SqlDataReader in this situation?
I am assuming you are not using a mocking framework. It would help to do so, but you should probably mock the IDataReader as suggested above. Here is a previous question that uses RhinoMocks. that may help.
Mocking a DataReader and getting a Rhino.Mocks.Exceptions.ExpectationViolationException: IDisposable.Dispose(); Expected #0, Actual #1
Also, I noticed you made an ISqlCommand, I suggest you use IDbCommand at it is the out of the box interface and will make your tests less brittle as it will allow substitution of other command objects if needed.
I just mocked the Data Reader and it runs fine:
Mock<IDataReader> mockDataReader = new Mock<IDataReader>();
bool success = true;
mockDataReader.Setup(x => x.Read())
.Returns(() => success).Callback(() => success = false);
Assert.IsTrue(mockDataReader.Object.Read());
Here is a good example: http://www.codeproject.com/Articles/478504/Moq-Mock-Database
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With