chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Any suggestions for mocking a call to SqlCommand.ExecuteReader? I want to ensure my code is handling the possilbe values returned from reader["fieldName"], mostly dbNull vs not null.

Thanks.
Scott C.
asked by scottctr (2.4k points)

8 Answers

0 votes
I found some code here in the forums that shows how to mock a SqlDataReader as an IDataReader, but I haven't been able to get it to work yet. Below is a test case that shows the trouble I'm having.

Thanks.
Scott C.

using System;
using System.Data;
using System.Data.SqlClient;

using NUnit.Framework;
using TypeMock;

namespace slc.TypeMock.Test
{
   /// <summary>
   /// Summary description for MockReaderTest.
   /// </summary>
   public class ReaderClass
   {
      public void ReadMethod()
      {
         using (SqlConnection conn = new SqlConnection("Server=server; Database=db; User ID=user;Password=pwd"))
         using (SqlCommand command = new SqlCommand("dbo.usp_FOOSP", conn))
         {
            command.CommandType = CommandType.StoredProcedure;
            conn.Open();
            using (IDataReader reader = command.ExecuteReader())
            {
               if (reader == null)
               {
                  throw new Exception("Reader not mocked");
               }
            }
         }
      }
   }
   
   [TestFixture]
   public class ReaderClassTest
   {
      [Test]
      public void TestIt()
      {
         MockManager.Init();
         MockManager.MockAll(typeof (SqlConnection)).ExpectCall("Open");
         
         MockObject mockReader = MockManager.MockObject(typeof (IDataReader));
         MockManager.MockAll(typeof (SqlCommand)).ExpectAndReturn("ExecuteReader", mockReader as IDataReader, 1);
         
         new ReaderClass().ReadMethod();
      }
   }
}
answered by scottctr (2.4k points)
0 votes
Hi Scot

OK we got few issues here:
1. The method ExecuteReader returns SqlDataReader object so you need to mock SqlDataReader object. The problem is that SqlDataReader has only private constructor so the line should look like this:
MockObject mockReader = MockManager.MockObject(typeof(SqlDataReader), Constructor.Mocked, null, null);


2. In order to to get the mocked object you should use the Object property of MockObject class. So the next line should look like this:

MockManager.MockAll(typeof(SqlCommand)).ExpectAndReturn("ExecuteReader", (SqlDataReader)mockReader.Object, 1);


3. And finally you need to mock the Close method of SqlConnection class or else you will get a nasty exception in your ReadMethod.

And here is the full code:



        [Test]
        public void TestIt()
        {
            MockManager.Init();
            Mock mockSqlCon = MockManager.MockAll(typeof(SqlConnection));
            mockSqlCon.ExpectCall("Open");
            mockSqlCon.ExpectCall("Close");

            MockObject mockReader = MockManager.MockObject(typeof(SqlDataReader), Constructor.Mocked, null, null);
            MockManager.MockAll(typeof(SqlCommand)).ExpectAndReturn("ExecuteReader", (SqlDataReader)mockReader.Object, 1);

            new ReaderClass().ReadMethod();
        }
answered by ohad (35.4k points)
0 votes
Thanks Ohad, but I'm getting an error saying that the constructor on SqlDataReader not found when using your code. Is this a version problem? I'm using .Net 1.1 and the free version of TypeMock 3.5.1.
answered by scottctr (2.4k points)
0 votes
Hi Scot

Yep you are right the error is because I'm using NET version 2.0
To fix the problem just remove one null argument from the call to MockObject
method. So the line in your code should look like this:
MockObject mockReader = MockManager.MockObject(typeof(SqlDataReader), Constructor.Mocked, null);
answered by ohad (35.4k points)
0 votes
Sorry Ohad, but I'm still getting the same error when removing the null argument. It looks to me that the only constructor takes an SqlCommand.
answered by scottctr (2.4k points)
0 votes
Hi Scot
OK I run it at .NET 1.1
The MockObject line should look like this:
MockObject mockReader = MockManager.MockObject(typeof(SqlDataReader), Constructor.Mocked, null as SqlCommand);

Please tell me if it works.
answered by ohad (35.4k points)
0 votes
Yep, that worked -- thanks!

Can I get someone to look at my post about mocking stored proc parameters and give me some pointers?
answered by scottctr (2.4k points)
0 votes
Hi Scot
I'm glad we solved it :D
Please Check your mailbox. I sent you a mail yesterday regarding your other problem 8)
answered by ohad (35.4k points)
...