Wie kann ich testen Controller.ViewData.ModelState
? Ich würde es vorziehen, es ohne ein Mock-Framework zu tun.
Ein virtueller Modifikator für Fehler wäre schön, aber leider gibt es eine Gestaltungssteuer, die mir ein wenig zu hoch erscheint.
Wie kann ich testen Controller.ViewData.ModelState
? Ich würde es vorziehen, es ohne ein Mock-Framework zu tun.
Sie müssen natürlich kein Mock verwenden, wenn Sie das Repository Pattern für Ihre Daten verwenden.
Einige Beispiele: http://www.singingeels.com/Articles/Test_Driven_Development_with_ASPNET_MVC.aspx
// Test for required "FirstName".
controller.ViewData.ModelState.Clear();
newCustomer = new Customer
{
FirstName = "",
LastName = "Smith",
Zip = "34275",
};
controller.Create(newCustomer);
// Make sure that our validation found the error!
Assert.IsTrue(controller.ViewData.ModelState.Count == 1,
"FirstName must be required.");
Ein virtueller Modifikator für Fehler wäre schön, aber leider gibt es eine Gestaltungssteuer, die mir ein wenig zu hoch erscheint.
IMHO ist die bessere Lösung, mvc-Förderer zu verwenden. Auf diese Weise erhalten Sie mehr realistisches Verhalten Ihres Controllers, sollten Sie Modell-Validierung zu seinem Schicksal liefern - Attribut-Validierungen. Unten Post ist dies zu beschreiben ( stackoverflow.com/a/5580363/572612 ).
//[Required]
//public string Name { get; set; }
//[Required]
//public string Description { get; set; }
ProductModelEdit model = new ProductModelEdit() ;
//Init ModelState
var modelBinder = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
() => model, model.GetType()),
ValueProvider=new NameValueCollectionValueProvider(
new NameValueCollection(), CultureInfo.InvariantCulture)
};
var binder=new DefaultModelBinder().BindModel(
new ControllerContext(),modelBinder );
ProductController.ModelState.Clear();
ProductController.ModelState.Merge(modelBinder.ModelState);
ViewResult result = (ViewResult)ProductController.CreateProduct(null,model);
Assert.IsTrue(result.ViewData.ModelState["Name"].Errors.Count > 0);
Assert.True(result.ViewData.ModelState["Description"].Errors.Count > 0);
Assert.True(!result.ViewData.ModelState.IsValid);
Ich mag diese Methode sehr. Wie Sie sagen, kann man damit ein Modell, das mit Validierungsattributen versehen wurde, viel besser testen.
Sehr praktisch. Ich denke, ich stimme im Allgemeinen mit Leuten, die sagen, dass Sie nicht Ihre Modelleigenschaften testen sollten, da dies ein Teil des Rahmens ist, aber es gibt Zeiten, wenn es kritisch ist, für alle zukünftigen Zeit zu bestätigen, dass Ihr Controller kritische Fehler fängt.
Ich versuche, einen gleichwertigen Code für die Web-API zu finden. Wenn jemand weiß, vielleicht könnte er hier aktualisieren?
Zum Testen der Web-API verwenden Sie die Validieren Sie Methode auf dem Controller:
var controller = new MyController();
controller.Configuration = new HttpConfiguration();
var model = new MyModel();
controller.Validate(model);
var result = controller.MyMethod(model);
Dieses Problem trat bei .NetCore 2.1 auf Hier ist meine Lösung:
Erweiterungsmethode
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace MyExtension
{
public static void BindViewModel<T>(this Controller controller, T model)
{
if (model == null) return;
var context = new ValidationContext(model, null, null);
var results = new List<ValidationResult>();
if (!Validator.TryValidateObject(model, context, results, true))
{
controller.ModelState.Clear();
foreach (ValidationResult result in results)
{
var key = result.MemberNames.FirstOrDefault() ?? "";
controller.ModelState.AddModelError(key, result.ErrorMessage);
}
}
}
}
Ansicht Modell
public class MyViewModel
{
[Required]
public string Name { get; set; }
}
Einheitstest
public async void MyUnitTest()
{
// helper method to create instance of the Controller
var controller = this.CreateController();
var model = new MyViewModel
{
Name = null
};
// here we call the extension method to validate the model
// and set the errors to the Controller's ModelState
controller.BindViewModel(model);
var result = await controller.ActionName(model);
Assert.NotNull(result);
var viewResult = Assert.IsType<BadRequestObjectResult>(result);
}
THIS! Warum funktioniert DNC2 nicht von Haus aus so :( Ich wollte nur einen Unit-Test machen, der sicherstellt, dass If !ModelState.IsValid, return BadRequest()
in einer Controller-Aktion
Funktioniert gut, es sei denn, das Modell ist ein IEnumerable. Ich hackte Ihren Code überprüfen, wenn das Modell ein IEnumerable dann durch jedes Modell tun die TryValidationObject Prüfung Schleife ist.
So können Sie nicht nur überprüfen, ob der Fehler existiert, sondern auch, ob er genau die gleiche Fehlermeldung hat wie erwartet. Zum Beispiel sind beide Parameter erforderlich, so dass ihre Fehlermeldung als "Erforderlich" angezeigt wird.
Modellauszeichnung:
//[Required]
//public string Name { get; set; }
//[Required]
//public string Description { get; set; }
Unit-Test-Code:
ProductModelEdit model = new ProductModelEdit() ;
//Init ModelState
var modelBinder = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
() => model, model.GetType()),
ValueProvider=new NameValueCollectionValueProvider(
new NameValueCollection(), CultureInfo.InvariantCulture)
};
var binder=new DefaultModelBinder().BindModel(
new ControllerContext(),modelBinder );
ProductController.ModelState.Clear();
ProductController.ModelState.Merge(modelBinder.ModelState);
ViewResult result = (ViewResult)ProductController.CreateProduct(null,model);
Assert.IsTrue(!result.ViewData.ModelState.IsValid);
//Make sure Name has correct errors
Assert.IsTrue(result.ViewData.ModelState["Name"].Errors.Count > 0);
Assert.AreEqual(result.ViewData.ModelState["Name"].Errors[0].ErrorMessage, "Required");
//Make sure Description has correct errors
Assert.IsTrue(result.ViewData.ModelState["Description"].Errors.Count > 0);
Assert.AreEqual(result.ViewData.ModelState["Description"].Errors[0].ErrorMessage, "Required");
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
0 Stimmen
Seien Sie genauer. Worauf wollen Sie den Test anwenden?