使用moq测试MVC

时间:2010-04-25 04:53:24

标签: .net unit-testing moq

我是moq的新手,我试图测试控制器(MVC)行为,当视图引发某个事件时,控制器在模型上调用某个函数,这里是类 -

public class Model
{
    public void CalculateAverage()
    {
        ...
    }

    ...
}

public class View
{
    public event EventHandler CalculateAverage;

    private void RaiseCalculateAverage()
    {
        if (CalculateAverage != null)
        {
            CalculateAverage(this, EventArgs.Empty);
        }
    }

    ...
}

public class Controller
{
    private Model model;
    private View view;

    public Controller(Model model, View view)
    {
        this.model = model
        this.view = view;
        view.CalculaeAverage += view_CalculateAverage;
    }

    priavate void view_CalculateAverage(object sender, EventArgs args)
    {
        model.CalculateAverage();
    }
}

和测试 -

[Test]
public void ModelCalculateAverageCalled()
{
    Mock<Model> modelMock = new Mock<Model>();
    Mock<View> viewMock = new Mock<View>();
    Controller controller = new Controller(modelMock.Object, viewMock.Object);
    viewMock.Raise(x => x.CalculateAverage += null, new EventArgs.Empty);
    modelMock.Verify(x => x.CalculateAverage());
    //never comes here, test fails in above line and exits
    Assert.True(true);
}

问题是测试在第二行的最后一行中失败,“调用未在mock上执行:x =&gt; x.CalculateAverage()”。我注意到的另一件事是测试终止于第二行,最后一行永远不会执行。我做的一切都正确吗?

1 个答案:

答案 0 :(得分:2)

请在下面找到工作代码段。不同之处在于“CalculateAverage”被声明为虚拟。原因是Moq在“Mock”类上创建了运行时包装器并覆盖了它的beheviour。但如果方法不是虚拟的,那么这是不可能的。

    public class Model
    {
        public virtual void CalculateAverage()
        {
        }
    }

    public class View
    {
        public virtual event EventHandler CalculateAverage;
    }

    public class Controller
    {
        private Model model;
        private View view;

        public Controller(Model model, View view)
        {
            this.model = model;
            this.view = view;
            view.CalculateAverage += view_CalculateAverage;
        }

        private void view_CalculateAverage(object sender, EventArgs args)
        {
            model.CalculateAverage();
        }
    }

    [TestFixture]
    public class MvcTest
    {
        [Test]
        public void ModelCalculateAverageCalled()
        {
            var modelMock = new Mock<Model>();
            var viewMock = new Mock<View>();

            var controller = new Controller(modelMock.Object, viewMock.Object);

            viewMock.Raise(x => x.CalculateAverage += null, EventArgs.Empty);
            modelMock.Verify(x => x.CalculateAverage());
        }
    }