Substituting a normal sql call with a replacement

There are many other ways to use mock objects with your tests than this example provides. The actual code is left out but here are some of the other types of testing scenarios we tested as we built this functionality. First is an approach that we think many will find appealling. For your test, you simply point your connection string to your normal test database, with the understanding that the test will not modify this data. At the same time, you want to specify Mock as the provider to avoid having to put commands in the AppContext. So, how do you simply stick in calls to your real provider except when you want your test to provide the data and/or intercept the command? The Mock provider has special functionality in the allowing you to pass through to other providers to build the data the MockDataReader will use. This is done by putting special files in the Mock cache directory. First an example for pulling test data from an xml serialized dataset.  Let's say that for the query_customer command we want to get the actual data from a file we have saved off.  In the Mock cache directory, you would put this file, mockreadertest.config to setup the test:

 

<?xml version="1.0" ?>
<DataFactory>
	<Reader statement="query_customer" provider="dataset" fileBaseName="query_customers" />
		
</DataFactory>

and then the actual data file called query_customers.xml as referred to in the setup file

<?xml 
version="1.0" standalone="yes"?> <query_customer>
<Table
  ID= "Table1">
    <companyname>Alfreds Futterkiste</companyname>
  </Table>
</query_customer>

 

the test would look like this. Especially pay attention to the name of the test, setup to hook this particular test to the config for the test list above.

[Test]
public void ReaderFromSerializedDataSet()
{
	
	Util.TestName = "mockreadertest";
	DataFactory fac = new DataFactory(conn, "Mock");
	IDbCommand comm = fac.GetCommand("query_customer");
	Assertion.AssertNotNull("command not returned", comm);
	IDataReader rdr = comm.ExecuteReader();
	Assertion.AssertNotNull("no reader returned", rdr);
	Assertion.Assert("no records returned", rdr.Read());
	Assertion.AssertEquals("didn't return correct data", "Alfreds Futterkiste", rdr.GetString(0));
}

 

An additional type of provider is supplied that helps with the normal data that should would have been retrieved by the code had the normal SqlClient provider been chosen. This provider simply sets up a different provider and passes the command on to it.

 

<?xml version="1.0" ?>
<DataFactory>
	<Reader statement="query_customer" provider="SqlClient" connectionString="trusted_connection=true;database=Northwind;server=localhost" />
	<Reader statement="query_customers_likeB" provider="SqlClient" connectionString="trusted_connection=true;database=Northwind;server=localhost" />
		
</DataFactory>

 

In this case, there are two command setup. "query_customers" when accessed by MockCommand will automatically call "query_customer" with the SqlClient provider. A second reader is also setup that could be used in a later test. The different types of providers can be mixed together of course so that for a given test scenario, you can provide your test data by any combination of building the reader in code, filling it from a saved dataset or querying a separate database for this data. This last option could also be used to put test data in a different type of database, such as ms access. The advantage there might by that you could use a simple copy command to restore the database to it's known good state during the [SetUp] method call. this combined with the ability of SnapDAL to to share sql statements between providers, allows for a pretty varied pallette of testing techniques.

 

By looking at the SnapDAL unit test code itself, you can get an in depth example of the different ways in which the code can be used. Look to MockProviderTests.cs in the SnapDAL.Tests project to find this code.