使用nunit对通用htmlHelper方法进行单元测试 [英] Unit testing generic htmlHelper methods with nunit

查看:80
本文介绍了使用nunit对通用htmlHelper方法进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是nUnit的新手,我受过为某些htmlhelper扩展方法创建单元测试的任务.

I'm new to nUnit and I've been tasked with creating unit tests for some htmlhelper extension methods.

如何为以下方法创建单元测试?

How should I go about creating a unit test for the following method?

    public static MvcHtmlString EnumDropDownListForOrderBy<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, bool orderById, string firstElement = null, object htmlAttributes = null)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        Type enumType = GetNonNullableModelType(metadata);
        IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();

        IEnumerable<SelectListItem> items = values.Select(value => new SelectListItem()
        {
            Text = value.GetAttributeFrom<DescriptionAttribute>(value.ToString()).Description,
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        });

        IEnumerable<SelectListItem> itemsFiltered = items.Where(e => !string.IsNullOrEmpty(e.Text)).AsEnumerable();

        itemsFiltered = itemsFiltered.OrderBy(e => (orderById ? e.Text : e.Value));

        return htmlHelper.DropDownListFor(
            expression,
            itemsFiltered,
            firstElement,
            htmlAttributes
        );
    }

任何帮助将不胜感激

推荐答案

下面是您为此编写单元测试的方式.请注意,由于您尚未指定使用Mock对象框架,因此我将采用穷人技术,即 Moq .

Below is how you write a Unit Test for this. Note that since you have not specified that you use a Mock object framework I'm going to the poor man technique, which is the hand written stubs and mocks. There is also another helper method if you are using Moq.

请注意,为了简化代码执行,我对扩展方法进行了几处更改,因此测试不会意外失败.无论如何,检查任何意外的行为者都是一种好的防御性编程实践.

It is important to note that, in order to simplify the code execution I have made couple of changes to your extension method, so the test would not fail unexpectedly. Checking for any unexpected behaver is a good defensive programming practice anyway.

返回测试.

SUT(被测系统)

这是SUT(被测系统)的外观和支持类型的外观. (请随时根据您的需要进行修改)

This is how the SUT (System Under Test) looks like and supporting types looks like. (Please feel free to modify to your need accordingly)

public static class MyHtmlHelper
{
    public static MvcHtmlString EnumDropDownListForOrderBy<TModel, TEnum>
         (this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TEnum>> expression,
        bool orderById, string firstElement = null, object htmlAttributes = null, 
        Func<ModelMetadata> fromLambFunc = null)
    {
        ModelMetadata metadata =
        ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);    
        Type enumType = GetNonNullableModelType(metadata);
        IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();

        IEnumerable<SelectListItem> items = 
            values.Select(value => new SelectListItem()
        {
            Text = GetText(value),
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        });

        IEnumerable<SelectListItem> itemsFiltered = 
        items.Where(e => !string.IsNullOrEmpty(e.Text)).AsEnumerable();
        itemsFiltered = itemsFiltered.OrderBy(e => (orderById ? e.Text : e.Value));

        return htmlHelper.DropDownListFor
        (expression, itemsFiltered, firstElement, htmlAttributes);
    }

    private static Type GetNonNullableModelType(ModelMetadata metadata) {
        return typeof (SomeEnum);
    }

    private static string GetText<TEnum>(TEnum value) {
        return value.GetAttributeFrom<DescriptionAttribute>(value.ToString()) != null
            ? value.GetAttributeFrom<DescriptionAttribute>(value.ToString()).Description
            : string.Empty;
    }
}

public static class ExtensionMethodsAttr
{
    public static T GetAttributeFrom<T>(this object instance, string propertyName) 
      where T : Attribute
    {
        var attrType = typeof(T);
        var property = instance.GetType().GetProperty(propertyName);

        return property != null ?
        (T)property.GetCustomAttributes(attrType, false).First() : default(T) ;
    }
}

public enum SomeEnum { A,}

单元测试

[TestFixture]
public class HtmlHelperTests
{
    [Test]
    public void EnumDropDownListForOrderBy_InvokeDropDownListFor_ReturnsExpectedSelectItemResult()
    {
        //Arrange
        var expected = "<select id=\"Foo\" name=\"Foo\"></select>";
        var fakeHtmlHelper = CreateHtmlHelperStaticStubs
        (new ViewDataDictionary(new FakeViewModel() {Foo = SomeEnum.A}));
        //var fakeHtmlHelper = CreateHtmlHelperUsingMoq
        (new ViewDataDictionary(new FakeViewModel(){Foo = SomeEnum.A}));

        //Act
        var result = fakeHtmlHelper.EnumDropDownListForOrderBy
        (model => model.Foo, It.IsAny<bool>(), null, null, null);

        //Assert
        Assert.AreEqual(expected, result.ToString());
    }


    private static HtmlHelper<FakeViewModel> 
         CreateHtmlHelperStaticStubs(ViewDataDictionary viewData)
    {
        var stubControllerContext = new ControllerContext(new FakeHttpContext(), new RouteData(), new FakeController());

        var stubViewContext = new ViewContext(stubControllerContext, new FakeView(),
            new ViewDataDictionary(new FakeViewModel() { Foo = SomeEnum.A }),
            new TempDataDictionary(), new TextMessageWriter());

        var fakeViewDataContainer = new FakeViewDataContainer();
        fakeViewDataContainer.ViewData = viewData;

        return new HtmlHelper<FakeViewModel>(stubViewContext, fakeViewDataContainer);
    }

    //Moq version
    private static HtmlHelper<FakeViewModel> 
       CreateHtmlHelperUsingMoq(ViewDataDictionary viewData)
    {
        var stubControllerContext = new Mock<ControllerContext>();
        stubControllerContext.Setup(x => x.HttpContext).Returns(new Mock<HttpContextBase>().Object);
        stubControllerContext.Setup(x => x.RouteData).Returns(new RouteData());
        stubControllerContext.Setup(x => x.Controller).Returns(new Mock<ControllerBase>().Object); ;

        var stubViewContext = new Mock<ViewContext>();
        stubViewContext.Setup(x => x.View).Returns(new Mock<IView>().Object);
        stubViewContext.Setup(x => x.ViewData).Returns(viewData);
        stubViewContext.Setup(x => x.TempData).Returns(new TempDataDictionary());

        var mockViewDataContainer = new Mock<IViewDataContainer>();

        mockViewDataContainer.Setup(v => v.ViewData).Returns(viewData);

        return new HtmlHelper<FakeViewModel>(stubViewContext.Object, mockViewDataContainer.Object);
    }
}   


class FakeHttpContext : HttpContextBase
{
    private Dictionary<object, object> _items = new Dictionary<object, object>();
    public override IDictionary Items { get { return _items; } }
}

class FakeViewDataContainer : IViewDataContainer
{
    private ViewDataDictionary _viewData = new ViewDataDictionary();
    public ViewDataDictionary ViewData { get { return _viewData; } set { _viewData = value; } }
}

class FakeController : Controller { }

class FakeView : IView
{
    public void Render(ViewContext viewContext, System.IO.TextWriter writer)
    {
        throw new NotImplementedException();
    }
}

public class FakeViewModel {
    public SomeEnum Foo { get; set; }
}

这篇关于使用nunit对通用htmlHelper方法进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆