Comment ModelBind test unitaire avec la validation des données Annotation?
-
11-09-2019 - |
Question
Je travaille sur l'application mvc asp.net en utilisant le cadre MVC2.
Voici la vue.
<% 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>
<% } %>
Voici la classe I utilisé pour modelbinding
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;
}
}
Et voici ma commande
[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);
}
Quand je fais le modèle de liaison, la validation d'annotation de données connaît déjà le modèle est invalide et ModelState.IsValid est faux.
Cependant, quand je fais le test unitaire, si je nourrir ma propre MenuCategoryBusinessObject dans la méthode d'action, il court-circuité le modelbinding, et ne connaît pas le ModelState est invalide.
[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);
}
Alors, mes questions est, comment peut effectivement test unitaire dans cette situation?
La solution
controllerInstance.ModelState.AddModelError("", "Dummy value.");
Ajout d'une valeur factice avant la méthode est appelée effacera la IsValid drapeau. Ensuite, il suffit d'appeler votre méthode d'action pour tester ce chemin de code particulier.
Autres conseils
Afin de tester si le modèle est correctement les données qui leur je ne serais probablement faire quelque chose entre les lignes:
[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);
}
L'autre chose que vous devez tester est que vous utilisez efficacement le DataAnnotationsModelBinder
au lieu de la valeur par défaut un:
ModelBinders.Binders.DefaultBinder = new DataAnnotationsModelBinder();