Как выполнить модульное тестирование ModelBind с проверкой аннотации данных?
-
11-09-2019 - |
Вопрос
Я работаю над asp.net приложением mvc, использующим фреймворк mvc2.
Вот такой вид.
<% using (Ajax.BeginForm("CreateMenuCategory",
"Admin",
new AjaxOptions { UpdateTargetId = "tabs-MenuCategories", }))
{ %>
<fieldset class="fields">
<legend>
Add Menu Categories
</legend>
<p>
<label for="MenuCategoryName">MenuCategory Name:</label>
<%= Html.TextBox("MenuCategoryName")%>
<%= Html.ValidationMessage("MenuCategoryName")%>
</p>
<p>
<label for="Description">Description</label>
<%= Html.TextBox("Description")%>
<%= Html.ValidationMessage("Description")%>
</p>
<p>
<label for="Notes">Notes</label>
<%= Html.TextBox("Notes")%>
</p>
<p class="submit">
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
Вот класс, который я использовал для привязки модели
public class MenuCategoryBusinessObject
{
//private readonly IMenuRepository _repository;
public int ID { get; set; }
[Required]
[StringLength(20)]
public string MenuCategoryName { get; set; }
[Required]
[StringLength(20)]
public string Description { get; set; }
public string Notes { get; set; }
public IEnumerable<MenuItemBusinessObject> MenuItems
{
get; set;
}
}
И вот мой контроль
[HttpPost]
public ActionResult CreateMenuCategory([Bind(Exclude = "ID")]MenuCategoryBusinessObject menuCategory)
{
if(ModelState.IsValid)
{//if I am valid.
_repository.CreateMenuCategory(menuCategory);
}
IndexMenuCategory model = new IndexMenuCategory
{
MenuCategories = _repository.GetMenuCategories(),
SelectedMenuCategory = null
};
return PartialView("MenuCategories", model);
}
Когда я выполняю привязку модели, проверка аннотации данных уже знает, что модель недопустима и ModelState.Значение isValid равно false .
Однако, когда я выполняю модульный тест, если я добавлю свой собственный MenuCategoryBusinessObject в метод action, он обойдет modelbinding и не будет знать, что ModelState неверен.
[Fact]
public void CreateNewMenuCategory()
{
// Setup
DataStore dataStore = new DataStore();
IMenuRepository menuRepository = new MenuRepository(dataStore);
MenuCategoryBusinessObject menuCategoryBusinessObject =
new MenuCategoryBusinessObject();
AdminController adminControl = new AdminController(menuRepository);
adminControl.SetFakeControllerContext();
adminControl.Request.SetHttpMethodResult("POST");
// Execute
adminControl.CreateMenuCategory(menuCategoryBusinessObject);
}
Итак, мои вопросы таковы: как можно эффективно провести модульное тестирование в этой ситуации?
Решение
controllerInstance.ModelState.AddModelError("", "Dummy value.");
Добавление фиктивного значения перед вызовом метода очистит Является действительным Отметить.Затем просто вызовите свой метод action, чтобы проверить этот конкретный путь к коду.
Другие советы
Чтобы проверить, правильно ли аннотированы данные модели, я бы, вероятно, сделал что-то из следующих строк:
[TestMethod]
public void Description_Should_Be_Required()
{
Expression<Func<MenuCategoryBusinessObject, object>> expression =
o => o.Description;
var me = expression.Body as MemberExpression;
var att = (RequiredAttribute[])me.Member
.GetCustomAttributes(typeof(RequiredAttribute), false);
att.Length.ShouldEqual(1);
}
Другая вещь, которую вам нужно проверить, - это то, что вы эффективно используете DataAnnotationsModelBinder
вместо стандартного:
ModelBinders.Binders.DefaultBinder = new DataAnnotationsModelBinder();