在私有方法中调用的模拟数据库对象
本文关键字:模拟 数据库 对象 调用 有方法 | 更新日期: 2023-09-27 18:31:00
我已经开始接触模拟框架,因为我想为(间接)向数据库写入某些内容的方法编写一些单元测试。下面是类结构的一个小示例:
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; }
}
我现在想做的是测试公共持久方法。这里的问题是,我的数据库对象将数据保存到数据库中。模拟 DatabaseObject 的 save 方法很容易,但我不确定将模拟对象注入 PersistImpl 方法的最佳方法是什么(如您所见,我对公共方法中的 DatabaseObject 一无所知)。其中一个方法是将数据库对象创建拉到公共方法中。所以像这样:
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);
}
但我对这种灵魂很不满意。我需要在持久性类之外创建数据库对象。
有没有解决此类问题的好方法?我肯定必须在我的单元测试中删除数据库访问权限。
解决问题的一种
方法是将DatabaseObject
对象的构造委托给工厂类:
interface IDatabaseObjectFactory
{
IDatabaseObject Create(DatabaseObjectData data);
}
class DatabaseObjectFactory : IDatabaseObjectFactory
{
public IDatabaseObject Create(DatabaseObjectData data)
{
return new DatabaseObject {DbObjectData = data };
}
}
class SomePersistenceClass
{
readonly IDatabaseObjectFactory _factory;
public SomePersistenceClass()
{
_factory = new DatabaseObjectFactory();
}
public SomePersistenceClass(IDatabaseObjectFactory factory)
{
_factory = factory;
}
public void Persist(object value, string type) { /* ... */ }
private void PersistImpl(IDatabaseObject dbObject) { /* ... */ }
private void PersistNumeric(int number)
{
//Some Calculations and Creation of DBObject
number++;
var dbObject = _factory.Create(new DatabaseObjectData {Number = number, Creator = "John Doe"});
PersistImpl(dbObject);
}
}
现在,如果您测试您的类,则可以传入一个返回不会访问您的数据库的FakeDatabaseObject
的FakeDatabaseObjectFactory
。
(但是,我发现您使用 DatabaseObject
类处理数据库访问的方式有点......奇怪;但这是另一个话题)。