我正在学习如何使用Moq和MSTest。在现有的应用程序中,我有以下要测试的方法:
/// <summary>
/// Return the marker equipment Id value give a coater equipment Id value.
/// </summary>
/// <param name="coaterEquipmentId">The target coater</param>
/// <returns>The marker equipment Id value</returns>
internal static string GetMarkerEquipmentId(string coaterEquipmentId)
{
return CicApplication.CoaterInformationCache
.Where(row => row.CoaterEquipmentId == coaterEquipmentId)
.Select(row => row.MarkerEquipmentId)
.First();
}
CicApplication 对象是一个'全局'对象,其属性名为CoaterInformationCache,它是CoaterInformation类的列表。
我假设我需要以某种方式模拟CicApplication.CoaterInformationCache,我可能需要将此方法传递给包含CoaterInformation类列表的接口,而不是通过仅在运行时包含值的全局对象访问列表? / p>
非常感谢
答案 0 :(得分:2)
全局/静态是单元可测试性的祸害。为了使这个可测试,你是正确的,你应该消除CicApplication
全局。您可以使用相同的公共API创建一个接口,即ICicApplication
,并将实例传递到您的应用程序代码中。
public interface ICicApplication
{
public List<CoaterInformation> CoaterInformationCache { get; }
}
public DefaultCicApplication : ICicApplication
{
public List<CoaterInformation> CoaterInformationCache
{
// Either use this class as an adapter for the static API, or move
// the logic here.
get { return CicApplication.CoaterInformationCache; }
}
}
由于这是一个静态方法,您可以将其作为方法参数传递,否则,将静态方法转换为实例方法,初始化对象上的ICicApplication
字段(可能将实例传递给构造函数)
然后,当您设置单元测试时,可以传入一个使用Moq设置的模拟实例:
Mock<ICicApplication> appMock = new Mock<ICicApplication>();
appMock
.SetupGet(ca => ca.CoaterInformationCache)
.Returns(new List<CoaterInformation> { ... });