How to mock an SqlDataReader using Moq - Update

后端 未结 5 1419
温柔的废话
温柔的废话 2021-01-30 17:12

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

5条回答
  •  说谎
    说谎 (楼主)
    2021-01-30 17:23

    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.

提交回复
热议问题