【发布时间】:2014-03-12 11:45:58
【问题描述】:
我正在尝试为一个大型项目编写单元测试,在该项目中,编码时从未考虑过可测试性。我已经开始模拟对象并编写测试,但我意识到我必须重构我们的很多代码才能模拟它。
这是我要为其创建测试的方法之一:
public List<DctmViewDefinition> GetDctmViewDefinitions()
{
List<DctmViewDefinition> dctmViewDefinitions = new List<DctmViewDefinition>();
DataPackage dataPackage = MyDfsUtil.GetObjectsWithContent();
foreach (DataObject dataObject in dataPackage.DataObjects)
{
DctmViewDefinition view = GetDctmViewDefinitionFromXmlFile(dataObject);
dctmViewDefinitions.Add(view);
}
return dctmViewDefinitions;
}
MyDfsUtil 类处理 web 服务调用,我想模拟它。 MyDfsUtil 分为 14 个部分类,每个类包含 300-500 行代码。所以有很多代码!
这是课程的摘录,为您提供想法:
public partial class MyDfsUtil
{
public string Locale { get; set; }
public string DfsServiceUrl { get; set; }
public string UserName { get; set; }
public DataPackage GetObjectsWithContent()
{
//Some code here
}
}
我使用的是起订量,因此我不能直接模拟这个类(据我所知)。我必须要么创建一个接口、一个抽象类,要么让这些方法成为虚拟的。 所以,我一直试图找出的是:为了能够模拟 MyDfsUtil,最好的方法是什么?
首先,我想创建一个界面,但是代码中使用的变量(Locale、UserName 等)呢?
其次,我尝试使用所有变量创建一个抽象基类 MyDfsUtilBase,并使基类中的方法返回 NotImplementedException。像这样:
public abstract class MyDfsUtilBase
{
public string Locale { get; set; }
public string DfsServiceUrl { get; set; }
public string UserName { get; set; }
public void GetObjectsWithContent()
{
throw new NotImplementedException();
}
}
然后 Resharper 告诉我在 MyDfsUtil 类中的 GetObjectsWithContent() 实现中添加“new”关键字。或者我可以将基类中的方法声明为虚拟方法,然后在实现上使用“覆盖”关键字。但是如果我必须声明我的方法是虚拟的,我可以在 MyDfsUtil 中做到这一点,然后我不需要创建一个抽象基类。 我一直在阅读有关虚拟方法的信息,似乎人们在是否使用它们上意见不一。在 MyDfsUtil 中使用虚拟方法将使我的重构分配更容易,并且使我能够模拟它们。像我这样的案例有什么最佳实践吗?
我正在尝试以最好、最简单的方式做到这一点。我没有单元测试或模拟的经验,我真的很想在不引入太多复杂性的情况下做到这一点。
【问题讨论】:
标签: c# unit-testing refactoring moq