We now have enough to compile the application and green light all the test cases. To do this, the mockServer.Expect method is used in conjunction with the Verify method to ensure that the call to Sync makes a single call to the Receive method of the mock object. If we removed the call to this method from the Sync method the unit test would fail, claiming that the call to the expected function was never made. Similarly, NMock supports three other methods to verify object behaviours. Contrary to the Expect method which accepts only the expected method name, ExpectAndReturn is used for methods that require return values. With a combination of these two, it is possible to use all the methods of a class in a unit test without invoking the class itself. Additionally, the ExpectAndThrow method is used to ensure that an exception is thrown. This is particularly useful when testing exception handling as it allows you to "fake" an exception in a controlled manner. Likewise, the ExpectNoCall can test that methods are not invoked. This can be a valuable debugging tool in situations where methods are called from multiple locations and you need to be sure that the correct pathway is being used to get there.
Mock objects can be used in place of either internal or external dependencies, ensuring that each test case only tests a maximum of one function.
Mocking SQL data connections with DotNetMock
Although it is possible to build mock objects for data classes with NMock, another framework called DotNetMock has some preconfigured classes for just this purpose. Like NMock, installing DotNetMock is just a matter of extracting the zip file to a suitable location. You will need to reference both the DotNetMock.DLL and DotNetMock.Framework.DLL files in your projects, however. Once you've got these files linked the DotNetMock.Framework.Data namespace will provide access to the DotNetMock Command, Parameter, DataReader, DataSet, DbConnection, DataAdapter and Transaction objects. Together these can be used to comprehensively simulate database interactions without calling upon a live database or the related classes. Not only does this perform code testing in the absence of a database, it also allows you to populate your mock objects with dummy data. Take the following unit test for example.
[Test]
public void TestInsertRecords()
{
cnn = new MockDbConnection();
MockCommand cmd = new _ MockCommand();
cnn.SetExpectedCommand(cmd);
cmd.SetExpectedCommandText _
(DatabaseClass.INSERTION_SQL);
cmd.SetExpectedExecuteCalls(1);
DatabaseClass myDBClass =
new _ DatabaseClass(cnn);
myDBClass.InsertNames();
cmd.Verify();
}