简体   繁体   English

ASP.MVC:如何对HTML标记帮助器进行单元测试

[英]ASP.MVC: How to unit test html tag helper

Is there any sophisticated way how to unit test the results of HtmlHelpers? 有什么复杂的方法可以对HtmlHelpers的结果进行单元测试吗? For example I have a helper that generates html markup for my custom inputs (I am using TagBuilder inside). 例如,我有一个帮助程序,用于为我的自定义输入生成html标记(我在内部使用TagBuilder)。 The result is IHtmlString which I have to convert to string and compare it with expected string in unit tests. 结果是IHtmlString,我必须将其转换为字符串并将其与单元测试中的预期字符串进行比较。 But this becomes very complicated, since in html I dont care about attributes order, I have to escape expected strings etc. Any ideas how to test it more cleaner? 但是,这变得非常复杂,因为在html中我不在乎属性顺序,因此我必须转义期望的字符串等。如何将其更干净地进行测试的任何想法?


SOLUTION: Based on comments and answers bellow I have started to write unit tests using HtmlAglityPack. 解决方案:根据下面的评论和答案,我已经开始使用HtmlAglityPack编写单元测试。 Code looks like this: 代码如下:

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"));

This is much more better than comparing two strings. 这比比较两个字符串要好得多。 No need to take care about attribute order and other stuff. 无需关心属性顺序和其他内容。

I answered this question which shows my unit tests for testing HtmlHelpers. 我回答了这个问题 ,该问题显示了用于测试HtmlHelpers的单元测试。

Here's the code for the testing 这是测试代码

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);
        }
    }

I'm using FakeItEasy for the fakes. 我将FakeItEasy用于假货。

What issues are you seeing when you testing? 测试时看到什么问题? Maybe post your code? 也许发布您的代码?

One way to test it is to create a transformation in the other way too, ie from html to some C# representation of your control. 测试它的一种方法是也以另一种方式创建转换,即从html到控件的某些C#表示形式。 This allows you to re-parse the generated HTML and verify things against the C# objects - and then, of course, attribute orders etc doesn't matter anymore. 这使您可以重新解析生成的HTML并针对C#对象进行验证-然后,当然,属性顺序等不再重要。

A sample test might look like this: 样本测试可能如下所示:

[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);
}

Of course, this adds complication to your tests since the parser is probably non-trivial. 当然,这会增加测试的复杂性,因为解析器可能很简单。 But that one is easier to test; 但这更容易测试。 just give it a couple of HTML samples and make sure the returned C# objects show the correct properties. 只需给它几个HTML示例,并确保返回的C#对象显示正确的属性。 If you find a case where the parser breaks the tests of your html helper, then you probably need to add a few test cases to the parser and fix those too. 如果您发现解析器破坏了html helper的测试的情况,那么您可能需要向解析器添加一些测试用例并进行修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM