Presenter中的单元测试方法,MVP

时间:2012-08-22 14:40:19

标签: c# unit-testing c#-4.0 moq mvp

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

  1. 复制原始集合。
  2. 对新系列进行排序。
  3. 理想情况下,id喜欢能够传入集合并进行测试以查看它是否正确排序。我还想验证方法1)被调用两次,请参阅下面基于以下内容的尝试: Example using 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>);
        }
    }
    

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

1 个答案:

答案 0 :(得分:3)

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

而不是:

var testObject = new MainPresenter(main, dialog);

你需要:

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

顺便说一下,通常认为不好的做法是明确验证某些特定方法的调用次数。这导致您的测试与特定实现之间的紧密耦合,从而导致脆弱的测试。

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

测试所涉及对象的最终状态要好得多,并使测试无法知道该状态是如何达到的。