C# – How test SqlParameter for equality

c#-2.0nmock2nunitsqlparameterunit-testing

Using NUnit and NMock2 I was not able to compare what I thought were the same SqlParameters:

SqlParameter param1 = new SqlParameter("@Id", 1);
SqlParameter param2 = new SqlParameter("@Id", 1);
Assert.IsTrue(param1.Equals(param2));  // This failed

I stumbled across this problem, when trying to test an execution of a method using NMock2

[Test]
    public void UpdateComments()
    {
        const int arbitraryId = 1;
        Comment comment = new Comment();

        SqlParameter idParam = new SqlParameter("@ChangeId", arbitraryId);

        Expect.Once.On(mockSqlDao).Method("ExecuteNonQuery")
              .With("usp_Update_Comment", idParam);

        changeDao.UpdateComment(arbitraryId, comment);

        mocks.VerifyAllExpectationsHaveBeenMet();
    }

I received this error:

NMock2.Internal.ExpectationException: unexpected invocation of sqlDao.ExecuteNonQuery("usp_Update_Comment", )
Expected:
1 time: sqlDao.ExecuteNonQuery(equal to "usp_Update_Comment", equal to <@ChangeId>) [called 0 times]

Questions:

  • How do you test with NMock2 when you
    expected Parameter is SqlParameter?
  • How do you compare equality of two SqlParameters?

Best Solution

Because .Equals() is using the default implementation of Equals as far as I know (which means that a SqlParameter will only "equal" another SqlParameter if they are the same object), you will need to directly interrogate the properties of the parameter to ensure the correct data is being passed.

The Has.Property call within .With allows you to check the properties of a parameter without requiring that a parameter equals some other value. Try the following:

Expect.Once.On(mockSqlDao).Method("ExecuteNonQuery")
          .With("usp_Update_Comment", Has.Property("ParameterName").EqualTo("@Id") & 
                                      Has.Property("Value").EqualTo(1));