I\'m new to moq and setting up mocks so i could do with a little help. How do I mock up an SqlDataReader using Moq?
Update
After further testing this is what I h
This does not let you mock a SqlDataReader
but if your function is returning a DbDataReader
(The base class of SqlDataReader
) or a IDataReader
the easist way to mock it is just use a DataTable
or a DataSet
and call its CreateDataReader() function and return that.
First, in a separate project, run your query like normal to produce some test data and use the WriteXmlSchema
to generate a .xsd file and the WriteXml
functions to hold the test data.
using (var con = new SqlConnection(connectionString))
{
con.Open();
using (var cmd = new SqlCommand("Some query", con))
{
DataSet ds = new DataSet("TestDataSet");
DataTable dt = new DataTable("FirstSet");
ds.Tables.Add(dt);
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
}
ds.WriteXmlSchema(@"C:\Temp\TestDataSet.xsd");
ds.WriteXml(@"C:\Temp\TestDataSetData.xml");
}
}
In your test project add TestDataSet.xsd
to the project and make sure it has the custom tool of MSDataSetGenerator
(it should have it by default). This will cause a DataTable
derived class named TestDataSet
to be generated that has the schema of your query.
Then add TestDataSetData.xml
as a resource to your test project. Finally in your test create the TestDataSet
and call ReadXml
using the text from the xml file you generated.
var resultSet = new TestData.TestDataSet();
using (var reader = new StringReader(Resources.TestDataSetData))
{
resultSet.ReadXml(reader);
}
var testMock = new Mock();
testMock.Setup(x => x.ExecuteReader())
.Returns(resultSet.CreateDataReader);
testMock.Setup(x => x.ExecuteReaderAsync())
.ReturnsAsync(resultSet.CreateDataReader);
This will create a data reader that will act just like the data reader that would have been returned from the sql query and even supports things like multiple result sets returned.