ASP.MVC:如何单元测试html标签助手

时间:2016-07-11 13:25:04

标签: c# html .net asp.net-mvc unit-testing

有没有复杂的方法如何对HtmlHelpers的结果进行单元测试?例如,我有一个帮助器为我的自定义输入生成html标记(我在里面使用TagBuilder)。结果是IHtmlString,我必须转换为字符串并将其与单元测试中的预期字符串进行比较。但这变得非常复杂,因为在HTML中我不关心属性顺序,我必须逃避预期的字符串等。任何想法如何测试它更清洁?

解决方案:根据评论和答案,我已经开始使用HtmlAglityPack编写单元测试。代码如下所示:

var states = new[] { MultiStateInputState.Unknown, MultiStateInputState.Yes, MultiStateInputState.No };

var actual = Html.Abb().MultiStateInput(states).Name("myinput").ToHtmlString();
var doc = new HtmlDocument();
var actualTextInput = doc.DocumentNode.ChildNodes.First(n => n.Name == "input");

 Assert.That(node, Is.Not.Null);
 Assert.That(node.Attributes, Is.Not.Null);
 Assert.That(node.Attributes, Is.Not.Empty);
 var attribute = node.Attributes.Single(a => a.Name == "name");
 Assert.That(attribute, Is.Not.Null);
 Assert.That(attribute.Value, Is.EqualTo("myinput"));

这比比较两个字符串要好得多。无需关注属性顺序和其他内容。

2 个答案:

答案 0 :(得分:1)

我回答了这个question,它显示了我测试HtmlHelpers的单元测试。

这是测试代码

public static class LabelExtensionFixtures
{
    [TestFixture]
    public class should_return_label_with_required_info : MvcExtensionFixtureBase
    {
        private class TestClass
        {
            [Required]
            public Guid Id { get; set; }
        }

        private MvcHtmlString _expectedResult;
        private HtmlHelper<TestClass> _sut;
        private MvcHtmlString _result;

        [SetUp]
        public void Given()
        {
            //arrange
            _expectedResult =
                MvcHtmlString.Create(
                    "<label class=\"control-label col-md-2\" for=\"Id\">Id<span class=\"required\">*</span></label>");
            _sut = CreateHtmlHelper(new TestClass {Id = Guid.NewGuid()});

            //act
            _result = _sut.LabelFor(model => model.Id, new { @class = "control-label col-md-2" }, "*");
        }

        [Test]
        public void Test()
        {
            //asert
            Assert.That(_result.ToHtmlString(), Is.EqualTo(_expectedResult.ToHtmlString()));
        }
    }
}

    public abstract class MvcExtensionFixtureBase
    {
        protected HtmlHelper<T> CreateHtmlHelper<T>(T instance)
        {
            var viewDataDictionary = new ViewDataDictionary<T>(instance);
            var viewContext = A.Fake<ViewContext>();
            A.CallTo(() => viewContext.ViewData).Returns(viewDataDictionary);

            var viewDataContainer = A.Fake<IViewDataContainer>();
            A.CallTo(() => viewDataContainer.ViewData).Returns(viewDataDictionary);

            return new HtmlHelper<T>(viewContext, viewDataContainer);
        }
    }

我使用FakeItEasy作假货。

您在测试时遇到了什么问题?也许发布你的代码?

答案 1 :(得分:1)

测试它的一种方法是以另一种方式创建转换,即从html到控件的某些C#表示。这允许您重新解析生成的HTML并根据C#对象验证事物 - 当然,属性命令等也不再重要。

示例测试可能如下所示:

[Fact]
public void ControlIsGeneratedCorrectly()
{
    var expected = new CustomControl { Foo = "Foo", Bar = 16 };

    var parser = new CustomControlParser();
    var model = new SomeViewModel { Foo = "Foo" };

    var actual = parser.Parse(Html.InputFor(model));

    Assert.AreEqual(expected.Foo, actual.Foo);
    Assert.AreEqual(expected.Bar, actual.Bar);
}

当然,这会增加测试的复杂性,因为解析器可能并不重要。但那个更容易测试;只需给它几个HTML示例,并确保返回的C#对象显示正确的属性。如果您发现解析器破坏了html帮助程序测试的情况,那么您可能需要向解析器添加一些测试用例并修复它们。