1

我试图测试一种组成控件集合的方法。它调用两种方法:

  1. 复制原始集合。
  2. 对新集合进行排序。

理想情况下,我希望能够传入一个集合并进行测试以查看它是否正确排序。我还想验证方法 1) 是否被调用了两次,请参见下面基于以下内容的尝试: 使用 RhinoMock 的示例

当我尝试创建 MainPresenter 实例时,以下测试会产生错误。错误的一般要点是“无法从 Moq.Mock 转换为”FrazerMann.CsvImporter.UserInterface.IMainForm。+ IFileDialog 的一个类似的。

    [Test]
    public void ComposeCollectionOfControls_CallSequence_4Calls()
    {
        var main = new Mock<IMainForm>();
        var dialog = new Mock<IFileDialog>();
        var temp = new Mock<IMainPresenter>();

        temp.Setup(s => s.PopulateLists<Control>(It.IsAny<TableLayoutPanel>(), It.IsAny<List<Control>>()));

        var testObject = new MainPresenter(main.Object, dialog.Object);
        testObject.ComposeCollectionOfControls(It.IsAny<object>(), It.IsAny<EventArgs>());
        temp.Verify(v => v.PopulateLists<Control>(It.IsAny<TableLayoutPanel>(), It.IsAny<List<Control>>()), Times.Once());          
    }

我想测试 ComposeCollectionOfControls 以确保 PopulateList() 被调用两次。

public interface IMainPresenter
{
    void PopulateLists<T>(TableLayoutPanel userInputs, List<T> container) where T : Control;
    int SortList<T>(T control1, T control2) where T : Control;
}

public class MainPresenter:IMainPresenter
{
    UserInputEntity inputs;

    IFileDialog _dialog;
    IMainForm _view;

    public MainPresenter(IMainForm view, IFileDialog dialog)
    {
        _view = view;
        _dialog = dialog;
        view.ComposeCollectionOfControls += ComposeCollectionOfControls;
        view.SelectCsvFilePath += SelectCsvFilePath;
        view.SelectErrorLogFilePath += SelectErrorLogFilePath;
        view.DataVerification += DataVerification;
    }

    public void ComposeCollectionOfControls(object sender, EventArgs e)
    {
        PopulateLists<TextBox>(_view.ColumnNameCtrls, _view.SortedColumnNameCtrls);
        _view.SortedColumnNameCtrls.Sort(SortList<TextBox>);
        PopulateLists<ComboBox>(_view.ColumnDataTypeCtrls, _view.SortedColumnDataTypeCtrls);
        _view.SortedColumnDataTypeCtrls.Sort(SortList<ComboBox>);
    }
}

有人可以给我一些关于如何做到这一点的指示吗?

4

1 回答 1

3

您看到的错误是因为您传递的是模拟类本身(类型为Moq.Mock),而不是 Moq 为您创建的模拟对象。

代替:

var testObject = new MainPresenter(main, dialog);

你需要:

var testObject = new MainPresenter(main.Object, dialog.Object);

顺便说一句,显式验证诸如对特定方法的调用次数之类的事情通常被认为是不好的做法。这会导致您的测试与特定实现之间的紧密耦合,从而导致脆弱的测试。

通过测试调用一个方法的次数,当代码的最终结果仍然正确时,您通常会在重构某些代码后发现测试失败。

最好测试所涉及对象的最终状态,并使您的测试不知道该状态是如何达到的。

于 2012-08-22T15:02:27.797 回答