【发布时间】:2013-09-12 21:08:36
【问题描述】:
我开始接触模拟框架,因为我想为(间接)向数据库写入内容的方法编写一些单元测试。 这是类结构的一个小例子:
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 会将数据保存到数据库中。模拟 DatabaseObject 的保存方法很容易,但我不确定将模拟对象注入 PersistImpl 的最佳方法是什么(如您所见,我对公共方法中的 DatabaseObject 没有任何了解)方法。一个想法是将 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);
}
但是我对这个灵魂很不满意。我需要在持久性类之外创建数据库对象。
有没有好办法解决这样的问题?我绝对必须在我的单元测试中删除数据库访问权限。
【问题讨论】:
-
为什么不在 SomePersistenceClass 的构造函数中注入一个 mock IDatabaseObject?
-
这是我现在正在考虑的事情。问题是,我不能使用相同的 DatabaseObject 而只是替换数据。有一些具有状态的数据库对象,所以我需要为每个要保存的对象创建一个自己的 DatabaseObject。
-
很公平,但都一样,哇。这听起来像是一个非常奇怪的设计 :) 在这种情况下,尽管下面的工厂模式肯定是你需要的。
标签: c# unit-testing mocking