i've started to get my hands on mocking frameworks because I want to write some unit tests for methods which (indirectly) write something to a database. Here's a small example of the classes structure:
class SomePersistenceClass
{
public void Persist(object value, string type)
{
if (type.Equals("Numeric"))
{
PersistNumeric( (int)value );
}
}
private void PersistNumeric(int number)
{
//Some Calculations and Creation of DBObject
number++;
var dbObject = new DatabaseObject {DbObjectData = new DatabaseObjectData {Number = number, Creator = "John Doe"}};
PersistImpl(dbObject);
}
private void PersistImpl(IDatabaseObject dbObject)
{
try
{
dbObject.Save();
}
catch (Exception)
{
//ErrorHandling
throw;
}
}
}
interface IDatabaseObject
{
DatabaseObjectData DbObjectData { get; set; }
void Save();
}
class DatabaseObject : IDatabaseObject
{
public DatabaseObjectData DbObjectData { get; set; }
public void Save()
{
//Save to Database;
}
}
class DatabaseObjectData
{
public int Number { get; set; }
public string Text { get; set; }
public string Creator { get; set; }
}
What I want to do now, is test the public persist method. The problem here is, that my DatabaseObject will save the data to an database. It would be easy to mock the DatabaseObject's save method, but I'm not sure what's the best way to inject the mocked object (as you can see, I don't have any knowledge of the DatabaseObject in my public method) into the PersistImpl method. One thougt was to pull up the DatabaseObject creation to the public method. So something like this:
public void Persist(object value, string type, IDatabaseObject dbObject)
{
if (type.Equals("Numeric"))
{
PersistNumeric( (int)value, dbObject );
}
}
private void PersistNumeric(int number, IDatabaseObject dbObject)
{
//Some Calculations and Creation of DBObject
number++;
dbObject.DbObjectData.Number = number;
dbObject.DbObjectData.Creator = "John Doe";
PersistImpl(dbObject);
}
But I'm quite unhappy with this soultion. I would need to create the database object outside the persistence class.
Is there are good way to solve such a problem? I definitly have to remove the database access within my unit tests.