In the past when I have been implementing unit test I have struggled to set up 'decent' unit tests for data access layers because they often have a database as an external dependency. In an ideal world I would mock the stored procedure calls so that the external dependency is removed.
However I have been unable to work out how to do this with the MOQ mocking framework, or find any other framework which supports this. Instead I have reverted to creating a scripted test database with known data in (so that I can always get outputs I expect) but this is slightly different from Mocking that layer.
Can anyone suggest how to Mock this part of the data access layer [I know for Entity Framework that https://effort.codeplex.com/ exists]?
Detail For instance if I have the following method
public object RunStoredProc()
{
//Some Setup
using (SqlConnection conn = new SqlConnection(CONNNECTION_STRING))
{
using (SqlCommand comm = new SqlCommand("storedProcName", conn))
{
conn.Open();
comm.CommandType = CommandType.StoredProcedure;
using (SqlDataReader reader = comm.ExecuteReader())
{
while (reader.Read())
{
//Logic
}
}
}
}
//Return object based on logic
}
then how do I mock the stored procedure output so that SQLDataReader
contains specified data. At a higher level I could mock the RunStoredProc()
method - but that won't help me test whether the logic in that method is correct. Alternatively I could strip the SQLReader
out into another method
public object RunStoredProc()
{
//Some Setup
List<object> data = GetData();
//Logic
//Return object based on logic
}
private List<object> GetData()
{
using (SqlConnection conn = new SqlConnection(CONNNECTION_STRING))
{
using (SqlCommand comm = new SqlCommand("storedProcName", conn))
{
conn.Open();
comm.CommandType = CommandType.StoredProcedure;
using (SqlDataReader reader = comm.ExecuteReader())
{
while (reader.Read())
{
//place into return object
}
}
}
}
}
but as the 'GetData' method should be private (not part of the published interface) I then wouldn't be able to mock that and so the issue remains.