0

我已经开始涉足单元测试,并创建了几个测试来测试我的演示者方法之一。此测试需要模拟我的数据访问类,特别是一种方法。这是我的数据访问类的原始方法:

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;
    }

我想用不同的场景测试演示者方法,例如:

  • 定期区域列表
  • 一个空的区域列表
  • 有重复的区域列表
  • 包含一个空字符串区域的列表或区域

我的第一个想法是为这些场景中的每一个创建一个单独的模拟数据访问类。我认为这有点麻烦,所以我稍微调整了该方法以允许读取不同的 xml 文件,其中包含特定于当前测试的数据。这是我的模拟方法的外观:

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 的值是从真正的 Presenter 类传递给这个方法的,并且从未使用过。

我知道这是错误的,但是应该如何实现呢?我应该创建一个单独的模拟数据访问类来设置每个测试数据场景吗?

4

1 回答 1

0

我通过在我的模拟数据访问类中公开一个公共字符串 (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);
    }

拉尔夫:感谢您的评论。这个问题与测试 Presenter.PopulateAreaComboBox 方法有关。本例中的GetAreaList 方法来自模拟数据访问类,只是简单地为被测方法提供测试数据。

于 2013-06-12T10:00:30.143 回答