C# ASP.NET核心中的单元测试标记帮助程序-填充标记公共属性

C# ASP.NET核心中的单元测试标记帮助程序-填充标记公共属性,c#,unit-testing,asp.net-core-mvc,tag-helpers,C#,Unit Testing,Asp.net Core Mvc,Tag Helpers,尝试在一个新项目上实现最佳实践,我想我应该看看我能将单元测试扩展到MVC标记帮助器的程度。在本例中,我有一个非常简单的助手,取自的标记助手部分,因此现在我有了 实际代码如下所示 public class EmailTagHelper : TagHelper { private const string EmailDomain = "contoso.com"; public string MailTo { get; set; } public override void

尝试在一个新项目上实现最佳实践,我想我应该看看我能将单元测试扩展到MVC标记帮助器的程度。在本例中,我有一个非常简单的助手,取自的标记助手部分,因此现在我有了

实际代码如下所示

public class EmailTagHelper : TagHelper
{
    private const string EmailDomain = "contoso.com";

    public string MailTo { get; set; }

    public override void Process(TagHelperContext ctx, TagHelperOutput output)
    {
        output.TagName = "a";
        var addr = $"{MailTo}@{EmailDomain}";
        output.Attributes.SetAttribute("href", $"mailto:{addr}");
        output.Content.SetContent(addr);
    }
}
生成的HTML与预期一样,如果我在运行代码时设置了断点,我可以看到pascal case
MailTo
正确地填充了C类中的camel case
MailTo

现在我有以下单元测试:

[TestMethod]        
public void EmailTagHelper_GeneratesExpectedHtml()
{
    var emailHelper = new EmailTagHelper();

    var ctx = new TagHelperContext(new TagHelperAttributeList
    {
        {"mail-to", "Support"}
    }, new Dictionary<object, object>(), Guid.NewGuid().ToString("N"));

    var output = new TagHelperOutput("email",
        new TagHelperAttributeList(), (useCachedResult, htmlEncoder) =>
        {
            var tagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.SetContent(string.Empty);
            return Task.FromResult<TagHelperContent>(tagHelperContent);
        });

    emailHelper.Process(ctx, output);
    Assert.AreEqual("a", output.TagName);
    Assert.AreEqual("mailto:Support@contoso.com", output.Attributes["href"].Value);
}
[TestMethod]
public void EmailTagHelper_GeneratesExpectedHtml()
{
var emailHelper=新的EmailTagHelper();
var ctx=新的TagHelperContext(新的TagHelperTributterList
{
{“邮寄至”,“支持”}
},new Dictionary(),Guid.NewGuid().ToString(“N”);
var output=新标记HelperOutput(“电子邮件”,
新标记HelperAttributeList(),(useCachedResult,htmlEncoder)=>
{
var tagHelperContent=new DefaultTagHelperContent();
tagHelperContent.SetContent(string.Empty);
返回Task.FromResult(tagHelperContent);
});
emailHelper.Process(ctx,输出);
Assert.AreEqual(“a”,output.TagName);
Assert.AreEqual(“mailto:Support@contoso.com,output.Attributes[“href”].Value);
}
第一个断言正在传递,如果我在tag helper类中设置了一个断点,我可以看到属性与正常运行应用程序时传递的属性相匹配,但是由于某种原因,在测试期间没有发生pascal到camel case
MailTo
的映射

我的工作是基于Github上的源代码,但我认为我遗漏了一些东西


有什么建议或者我必须在我的测试中设置
emailHelper.MailTo
,老实说,如果是这样的话,这看起来有点像是逃避回答:(希望这只是我忽略的一个细微差别!

看起来你没有在测试的系统上设置属性

这意味着这行代码

var addr = $"{MailTo}@{EmailDomain}";
如果处理时
MailTo
为空,则不会生成预期的电子邮件地址

在代码自定义实现中,没有任何地方可以访问上下文,因此,除非您实际设置了
MailTo
属性,否则在单元测试中调用
Process
时,它不会有值


当在实时代码中运行时,框架会解释razor并为您填充属性,但在单元测试中并非如此。

这是我的怀疑,razor以某种方式介入并在允许标记助手实际运行之前进行映射……他们这样做有点恼人,但我可以看到w为什么他们已经这么做了。我将不得不看看我是否能找到这是如何发生的,也许能实现一个测试版本。尽管如此,感谢您的输入!至少是按照正确的思路工作的:)我可能认为调用
emailHelper.Init(ctx)
可能会处理这个问题,但它似乎完全是在这个TagHelper类之外处理的;不知何故。@JakHammond是的,我建议您查看您在OP中链接的他们的测试。我注意到他们可能正在创建一个视图上下文,并将其分配给帮助者,以执行您所需的操作。检查这个测试
var addr = $"{MailTo}@{EmailDomain}";