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
I'm trying to verify the parameters on a stored proc that takes several parameters.

Here's the code I'm using:
private void QueuePlayerUpdate(int playerID, bool newAccount, bool editedAccount, bool newPlayer, bool editedPlayer, int userID, int applicationID, int workstationID)
{
    using (SqlConnection conn = new SqlConnection(OasisSqlDataManager.ConnectionString()))
    using (SqlCommand command = new SqlCommand("dbo.CPW_INS_PLAYER_PRESTAGE", conn))
    {
      command.CommandType = CommandType.StoredProcedure;
      command.Parameters.Add("@iPLAYER_ID", playerID);
      command.Parameters.Add("@iAccountNew", newAccount);
      //...more parameters
      conn.Open();
      command.ExecuteNonQuery();
    }
}


Here's my test:
[Test] public void TestQueueNewPlayer()
{
   MockManager.MockAll(typeof (SqlCommand)).ExpectAndReturn("ExecuteNonQuery", 1, 1);
   Mock parametersMock = MockManager.Mock(typeof(SqlParameterCollection));
   parametersMock.ExpectUnmockedCall("Add", 1).Args("@iPLAYER_ID", 1);
   parametersMock.ExpectUnmockedCall("Add", 1).Args("@iAccountNew", false);
   //...more parameters         
   new v11OneCardBridgeDAL().QueueNewPlayer(1, 1, 1, 1);
}


I'm getting this error:
SqlParameterCollection.Add expected 2 parameters but received 1


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

2 Answers

0 votes
Here's a simplified test case:

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 TestClass
   {
      public void MockMultipleParametersMethod()
      {
         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();
            command.Parameters.Add("@param1", 1);
            command.Parameters.Add("@param2", 2);
            command.ExecuteNonQuery();
         }
      }
   }
   
   [TestFixture]
   public class ReaderClassTest
   {
      [Test]
      public void TestMultipleParameters()
      {
         MockManager.Init();
         MockManager.MockAll(typeof (SqlConnection)).ExpectCall("Open");
         
         MockManager.MockAll(typeof (SqlCommand)).ExpectAndReturn("ExecuteNonQuery", 1, 1);
         Mock parametersMock = MockManager.Mock(typeof(SqlParameterCollection));
         parametersMock.ExpectUnmockedCall("Add", 1).Args("@param1", 1);
         parametersMock.ExpectUnmockedCall("Add", 1).Args("@param2", 2);
         
         new TestClass().MockMultipleParametersMethod();
         MockManager.ClearAll();
      }
   }
}
answered by scottctr (2.4k points)
0 votes
Hi Scot
The reason for the message you got is that the Add method calls internally to another Add method.
The best solution in this case is to use the IParameters method 'When'.
'When' method is actually a conditional expectation.
Here is how it should be used in your code:

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

            MockManager.MockAll(typeof(SqlCommand)).ExpectAndReturn("ExecuteNonQuery", 1, 1);
            Mock parametersMock = MockManager.Mock(typeof(SqlParameterCollection), Constructor.NotMocked);

            parametersMock.ExpectUnmockedCall("Add", 1).When("@param1", 1);
            parametersMock.ExpectUnmockedCall("Add", 1).When("@param2", 2);

            new TestClass().MockMultipleParametersMethod();
            MockManager.ClearAll();
        } 


Two important notes:
1. Notice the line:

Mock parametersMock = MockManager.Mock(typeof(SqlParameterCollection), Constructor.NotMocked);

You can see that we don't want to mock the constructor otherwise we will get System.NullReferenceException inside the Add method.

2. The 'When' method is supported only in the enterprise version.
answered by ohad (35.4k points)
...