单元测试自定义 TagHelper,其中 HTML 根据模型属性上的 ValidationAttribute 有条件地呈现

Cia*_*ran 8 unit-testing validationattribute asp.net-core-mvc asp.net-core-tag-helpers

我有一个自定义 TagHelper,它扩展了 OOTB InputTagHelper。我根据与其关联的模型属性上存在的自定义 ValidationAttribute 有条件地向其添加属性。TagHelper.Process方法中的代码工作正常:

if (this.For.Metadata.ValidatorMetadata.OfType<NumericValidationAttribute>().Any())
{
   output?.Attributes.SetAttribute(new TagHelperAttribute("inputmode", "numeric"));
   output?.Attributes.SetAttribute(new TagHelperAttribute("pattern", "[0-9]*"));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是在单元测试中。我使用 Net Core MVC 测试存储库中提供的代码编写了其他单元测试:https : //github.com/aspnet/Mvc/blob/master/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/

...但没有真正指导如何为我要测试的属性创建Forie ModelExpression,该属性具有与之关联的 Validation 属性:例如

    public class TestModel
    {
        [NumericValidation(ErrorMessage = "Error message")]
        public string Field1 { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我希望能够填充For.Metadata.ValidatorMetadata此 ModelExpression的列表,但我不知道如何。

不起作用的完整单元测试是:

[Fact]
        public void CustomInputTagHelperProcess_NumericValidationAttributeOnModelProperty_GeneratesCorrectHtml()
        {
            // Arrange
            var metadataProvider = new EmptyModelMetadataProvider();
            var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
            var model = new TestModel
            {
                Field1 = "cc",
            };
            var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(TestModel), model);
            var modelExpression = new ModelExpression(name: "Field1", modelExplorer: modelExplorer);
            var viewContext = TestableHtmlGenerator.GetViewContext(model, metadataProvider);

            var attributes = new TagHelperAttributeList
            {
                { "name", PropertyName },
                { "type", InputTypeName },
            };

            var tagHelperContext = new TagHelperContext(attributes, new Dictionary<object, object>(), nameof(CustomInputTagHelperTest));

            var output = new TagHelperOutput(
                Input,
                new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(result: null))
            {
                TagMode = TagMode.SelfClosing,
            };

            var customInputTagHelper = new CustomInputTagHelper(this.htmlGenerator)
            {
                For = this.modelExpression,
                InputTypeName = InputTypeName,
                Name = PropertyName,
                ViewContext = this.viewContext,
            };

            // Act
            customInputTagHelper.Process(this.tagHelperContext, output);

            // Assert - ensure we have an inputmode attribute on the input.
            Assert.Contains(output.Attributes, x => x.Name == "inputmode" && x.Value.ToString() == "numeric");
        }
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?