尝试使用Moq模拟HtmlHelper时抛出MissingMethodException

Med*_*Man 4 asp.net-mvc unit-testing moq mocking

当试图跟随关于使用Moq模拟htmlhelper的文章时,我遇到了以下问题.创建htmlhelper时会抛出异常.我只是猜测正在使用城堡windsor(通过查看错误消息).

例外:

发生了MissingMethodException

找不到类型为"Castle.Proxies.ViewContextProxy"的构造函数.

堆栈跟踪:

在System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr,Binder binder,Object [] args,CultureInfo culture,Object [] activationAttributes)

代码:

    public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd)
    {
        Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
                                                new ControllerContext(
                                                    new Mock<HttpContextBase>().Object,
                                                    new RouteData(),
                                                    new Mock<ControllerBase>().Object),
                                                new Mock<IView>().Object,
                                                vd,
                                                new TempDataDictionary());

        Mock<IViewDataContainer> mockViewDataContainer = new Mock<IViewDataContainer>();
        mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);

        return new HtmlHelper(mockViewContext.Object, mockViewDataContainer.Object);
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用ASP MVC 2,Moq 4.0 beta 3,VS2010,使用IDE的测试框架.

如何解决问题并返回HtmlHelper的实例?

Igo*_*aka 7

MissingMethodException当MOQ无法Mock<>()将参数与mocked类的构造函数上的参数匹配时,就会得到.

看着ViewContext解释原因.只有一个构造函数重载,它是这样的:

 public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer);
Run Code Online (Sandbox Code Playgroud)

此设置(包括缺少TextWriter模拟)应该工作:

   Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
     new ControllerContext(
     new Mock<HttpContextBase>().Object,
     new RouteData(),
     new Mock<ControllerBase>().Object),
     new Mock<IView>().Object,
     vd,
     new TempDataDictionary()
     new Mock<TextWriter>().Object);
Run Code Online (Sandbox Code Playgroud)

PS MOQ使用Castle Dynamic Proxy在运行时创建模拟类,因此在您看到的异常中名称为Castle.Castle Windsor使用动态代理项目,但它们是完全不同的项目.


Håv*_*d S 2

我已使用我的博客文章中的代码重现了您的问题。以下更新的方法对我有用:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary vd)
{
    Mock<ViewContext> mockViewContext = new Mock<ViewContext>(
        new ControllerContext(
            new Mock<HttpContextBase>().Object,
            new RouteData(),
            new Mock<ControllerBase>().Object),
        new Mock<IView>().Object,
        vd,
        new TempDataDictionary(),
        new Mock<TextWriter>().Object);

    mockViewContext.Setup(vc => vc.ViewData).Returns(vd);

    var mockViewDataContainer = new Mock<IViewDataContainer>();
    mockViewDataContainer.Setup(v => v.ViewData)
        .Returns(vd);

    return new HtmlHelper(mockViewContext.Object,
                            mockViewDataContainer.Object);
}
Run Code Online (Sandbox Code Playgroud)

我也在我的博客上发布了更新。