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
0 votes
Is it possible to mock overloaded instance methods with natural mocks? Seems like it works with static methods.

I have an implemenation of a database connection class that overloads the CreateCommand call such as:

public class MyDbConnection {

public MyDbCommand CreateCommand(string sql) {
return CreateCommand(sql, DEFAULT_TIMEOUT);
}

public MyDbCommand CreateCommand(string sql, int timeout) {
//implementation not important.
}
}

If I mock the call to CreateCommand like this:

using (RecordExpectations recorder = RecorderManager.StartRecording()) {
conn.CreateCommand(string.Empty);
recorder.CheckArguments(Check.CustomChecker(sqlVerify.SaveSql, null));
recorder.CallOriginal();
recorder.RepeatAlways();
}

I get an exception at runtime:

TypeMock.VerifyException:
TypeMock Verification: Call to TetraData.UnitTesting.Data.MockTDDbConnection.CreateCommand() 1 Parameters expected but received 2

at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)
at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected, Object p1, Object p2)
at TetraData.Common.SQL.TDDbConnection.CreateCommand(String cmdText, Int32 commandTimeout) in TDDbConnection.cs:line 247
at TetraData.Common.SQL.TDDbConnection.CreateCommand(String cmdText) in TDDbConnection.cs:line 237

It looks like the first call to CreateCommand is mocked properly, but because the overload just routes it's implementation to the second overload, TypeMock doesn't seem to like it.

But if I add both overloads to the using block, then everything works as expected.

Is this how it is supposed to work? Is this in the documentation somewhere?
asked by ksummerlin (4k points)

2 Answers

0 votes
Hi
I think this can be a nice feature of natural mocks and we added it to
our feature list.

Until we implement the feature you can use the following workaround:
mock the second overloaded method and use
recorder.CallOriginal() and recorder.RepeatAlways()
Like this:
[Test]
public void testMethod()
{
   using (RecordExpectations recorder = RecorderManager.StartRecording())
   {
      MyDbConnection conn = new MyDbConnection();
      conn.CreateCommand(string.Empty);
      recorder.CheckArguments(Check.CustomChecker(sqlVerify.SaveSql, null));                 
      recorder.CallOriginal();
      recorder.RepeatAlways();

      conn.CreateCommand(string.Empty, 0);
      recorder.CallOriginal();
      recorder.RepeatAlways();
   }


This is not a perfect solution :?
but it should work until we'll implement this feature.
answered by ohad (35.4k points)
0 votes
That is pretty much what I ended up using in my test and it does work. I had one other test that is similar to this, but the overloads are in a base class. In the base class scenario, this does not work quite right. Over the next couple of days I'll try to get a small demonstration of that code and post it to the features group.

Thanks
answered by ksummerlin (4k points)
...