ASP. NET MVC: редактор модульных тестов для генерирует пустую строку MvcHtmlString - PullRequest
0 голосов
/ 26 марта 2020

Я работаю над проектом MVC 5, и у меня есть модульный тест, который проверяет сгенерированную разметку html для пользовательского html помощника.

private class Faq
    {
        [RequiredIfMultiple(new string[] { "SickLeave", "Holidays" }, new object[] { 2, 2 })]
        [RequiredIfMultiple(new string[] { "SickLeave1", "SickLeave2", "SickLeave3" }, new object[] { 2, 2, 2 })]
        public string Property { get; set; }
    }

[Test]
    public void HtmlString_With_RequiredIfMultiple_Test()
    {
        //Arrange
        Expression<Func<Faq, string>> expression = (t => t.Property);

        //Act
        IHtmlString result = htmlHelper.EditorForRequiredIf(expression);

        // Assert
        Assert.IsTrue(result.ToString().Contains("data-val-requiredifmultiple"));
    }

html вспомогательное расширение EditorForRequiredIf

public static MvcHtmlString EditorForRequiredIf<TModel, TValue>(this HtmlHelper<TModel> helper
        , Expression<Func<TModel, TValue>> expression
        , string templateName = null
        , string htmlFieldName = null
        , object additionalViewData = null)
    {
        string mvcHtml = EditorExtensions.EditorFor(helper, expression, templateName, htmlFieldName, additionalViewData).ToString();            
        string element = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));
        string key = helper.ViewData.Model.ToString() + "." + element;

        if (RequiredIfMultipleAttribute.CountPerField != null)
        {
            RequiredIfMultipleAttribute.CountPerField.Remove(key);
            if (RequiredIfMultipleAttribute.CountPerField.Count == 0)
            {                    
                RequiredIfMultipleAttribute.CountPerField = null;
            }
        }

        string pattern = @"data\-val\-requiredif[a-z]+";

        return Regex.IsMatch(mvcHtml, pattern) ? MergeClientValidationRules(mvcHtml) : MvcHtmlString.Create(mvcHtml);
    }

Оказавшись в представлении, EditorFor вызывает GetClientValidationRules метод для пользовательского атрибута RequiredIfMultipleAttribute для сгенерируйте html разметку с правильными тегами data-val.

GetClientValidationRules метод:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        int count = 0;
        string key = metadata.ContainerType.FullName + "." + metadata.PropertyName;            

        if (CountPerField == null)
        {
            CountPerField = new Dictionary<string, int>();
        }

        if (CountPerField.ContainsKey(key))
        {               
            count = ++CountPerField[key];
        }
        else
        {
            CountPerField.Add(key, count);
        }

        yield return new RequiredIfMultipleValidationRule(ErrorMessageString, Props, Vals, count);
    }

Так что на производстве все это работает отлично. Но во время тестов у меня ужасное время. Я получаю пустую строку на string mvcHtml = EditorExtensions.EditorFor(helper, expression, templateName, htmlFieldName, additionalViewData).ToString(); и в стеке вызовов, я не вижу, чтобы был вызван метод GetClientValidationRules .

С другой стороны С другой стороны, если я изменю EditorExtensions.EditorFor на InputExtensions.TextBoxFor , я вижу, что MvcHtmlString генерируется правильно и GetClientValidationRules вызывается.

У кого-нибудь есть подсказка? и я надеюсь, что я достаточно ясно.

1 Ответ

0 голосов
/ 26 марта 2020

Чтобы атрибут работал, какой-то фрагмент кода, который выполняет ваш метод, должен его распознать и как-то воздействовать на него. Когда вы запускаете свой код в рабочей среде, это то, что Asp. Net MVC делает для вас.

Ваш тест выполняется NUnit, а не Asp. Net. NUnit ничего не делает с атрибутом, потому что он не предназначен для этого. Если вы подумаете об этом, вы поймете, что NUnit не может распознать и воздействовать на все различные атрибуты, известные всем хостам, на которых может выполняться рабочий код.

В результате любое использование вами этот атрибут должен быть в самом приложении MVC, а не в вашем тесте.

...