我已经开始涉足单元测试,并创建了几个测试来测试我的演示器方法之一。这个测试需要模拟我的数据访问类,特别是一个方法。这是我的数据访问类的原始方法:
public IEnumerable<IArea> GetAreaList()
{
ConnectToTFSProject();
XmlNode areaNode = GetAreaNode();
List<IArea> areaList = new List<IArea>();
foreach (XmlNode node in areaNode.FirstChild.ChildNodes)
{
IArea area = new Area() { AreaName = node.Attributes["Name"].Value };
areaList.Add(area);
}
areaList.Sort();
return areaList;
}
我想用不同的场景来测试presenter方法,例如:
- 区域常规列表
- 区域空列表
- 有重复项的区域列表
- 包含一个空字符串区域的列表或区域
我的第一个想法是为每个场景创建一个单独的模拟数据访问类。我认为这有点麻烦,所以我稍微调整了一下方法,允许读取不同的xml文件,其中包含特定于当前测试的数据。下面是我的mock方法:
public IEnumerable<IArea> GetAreaList(string dataSource)
{
List<IArea> areaList = new List<IArea>();
XmlTextReader areaReader = new XmlTextReader(dataSource);
while (areaReader.Read())
{
if (areaReader.NodeType == XmlNodeType.Text)
areaList.Add(new Area() { AreaName = areaReader.Value });
}
return areaList;
}
这个模拟方法将从PresenterTest类调用,如下所示:
[TestMethod]
public void PopulateAreaComboBox_WithValidAreaList()
{
//Act
_presenter.PopulateAreaComboBox(mockFolderPath + "MockAreaList.xml");
//Assert
Assert.AreEqual(3, _view.AreaListLoaded.Count);
}
[TestMethod]
public void PopulateAreaComboBox_WithEmptyAreaList()
{
//Act
_presenter.PopulateAreaComboBox(mockFolderPath + "MockEmptyAreaList.xml");
//Assert
Assert.AreEqual(0, _view.AreaListLoaded.Count);
}
现在,我在这里遇到的问题是,我现在需要改变我的原始方法的签名(通过添加对dataSource参数的引用):
public IEnumerable<IArea> GetAreaList(string dataSource)
因为这个参数只对单元测试是必需的,所以null值是从真正的演示器类传递到这个方法的,并且永远不会使用。
我知道这是错误的,但这应该如何完成?我是否应该创建一个单独的模拟数据访问类来设置每个测试数据场景?
我通过在模拟数据访问类中公开一个公共字符串(TestDataXml)来解决这个问题。然后为每个测试创建一个模拟数据访问类的新实例,每次将此字符串设置为单个测试数据xml文件的位置:
class MockDataRetrieval : IDataRetrieval
{
public string TestDataXml { get; set; }
public IEnumerable<IArea> GetAreaList()
{
List<IArea> areaList = new List<IArea>();
XmlTextReader areaReader = new XmlTextReader(TestDataXml);
while (areaReader.Read())
{
if (areaReader.NodeType == XmlNodeType.Text)
areaList.Add(new Area() { AreaName = areaReader.Value });
}
return areaList;
}
}
从PresenterTest类调用模拟方法:
[TestMethod]
public void PopulateAreaComboBox_WithValidAreaList()
{
//Arrange
_data = new MockDataRetrieval() { TestDataXml = mockFolderPath + "MockAreaList.xml" };
_view = new MockMainForm();
_presenter = new TestCasePresenter(_view, _data);
//Act
_presenter.PopulateAreaComboBox();
//Assert
Assert.AreEqual(3, _view.AreaListLoaded.Count);
}
[TestMethod]
public void PopulateAreaComboBox_WithEmptyAreaList()
{
//Arrange
_data = new MockDataRetrieval() { TestDataXml = mockFolderPath + "MockEmptyAreaList.xml" };
_view = new MockMainForm();
_presenter = new TestCasePresenter(_view, _data);
//Act
_presenter.PopulateAreaComboBox();
//Assert
Assert.AreEqual(0, _view.AreaListLoaded.Count);
}
拉尔夫:谢谢你的评论。这个问题与测试演示者有关。PopulateAreaComboBox方法。本例中的GetAreaList方法来自模拟数据访问类,并简单地为被测方法提供测试数据。