ASP.NET MVC Web アプリケーションの最初の単体テストを作成しました。すべて正常に動作し、貴重な情報も得られていますが、ビュー モデルでエラーをテストできません。一部の値が入力されていない場合 (空の文字列または null) でも、ModelState.IsValid は常に true になります。
投稿されたデータがモデルにマッピングされたときにモデル検証が行われ、モデル検証を自分で行うためのコードを記述する必要があることはすでに読んだことがあります。
リンクされた Web ページで提供されている 3 つの例を試してみましたが、うまく機能しないようです。
いくつかのコード:
私のビューモデル
...
[Required(ErrorMessageResourceName = "ErrorFirstName", ErrorMessageResourceType = typeof(Mui))]
[MaxLength(50)]
[Display(Name = "Firstname", ResourceType = typeof(Mui))]
public string FirstName { get; set; }
...
コントローラー
...
[HttpPost]
public ActionResult Index(POSViewModel model)
{
Contract contract = contractService.GetContract(model.ContractGuid.Value);
if (!contract.IsDirectDebit.ToSafe())
{
ModelState.Remove("BankName");
ModelState.Remove("BankAddress");
ModelState.Remove("BankZip");
ModelState.Remove("BankCity");
ModelState.Remove("AccountNr");
}
if (ModelState.IsValid)
{
...
contractValidationService.Create(contractValidation);
unitOfWork.SaveChanges();
return RedirectToAction("index","thanks");
}
else
{
return Index(model.ContractGuid.ToString());
}
}
私のユニットテスト
posViewModel.FirstName = null;
posViewModel.LastName = "";
...
var modelBinder = new ModelBindingContext()
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => posViewModel, posViewModel.GetType()),
ValueProvider = new NameValueCollectionValueProvider(new System.Collections.Specialized.NameValueCollection(), CultureInfo.InvariantCulture)
};
var binder = new DefaultModelBinder().BindModel(new ControllerContext(), modelBinder);
posController.ModelState.Clear();
posController.ModelState.Merge(modelBinder.ModelState);
ActionResult result = posController.Index(posViewModel);
//Assert
mockContractValidationService.Verify(m => m.Create(It.IsAny<ContractValidation>()), Times.Never);
Assert.IsInstanceOfType(result, typeof(ViewResult));
ビューでは、目立たない JavaScript 検証を使用しており、正常に動作しています。
ベストアンサー1
同時に 2 つの異なるものをテストしようとしています。コントローラはモデルの状態を検証する責任はなく、検証の結果に基づいて異なる動作をするだけです。したがって、コントローラの単体テストでは検証をテストすべきではなく、別のテストで行う必要があります。私の意見では、3 つの単体テストが必要です。
- モデルの検証が正しく行われているかどうかを検証するもの
- モデル状態が有効な場合にコントローラが正しく動作するかどうかを検証するもの
- モデル状態が無効な場合にコントローラが正しく動作するかどうかを検証するもの
やり方は次のとおりです:
1.モデルの検証
[Test]
public void test_validation()
{
var sut = new POSViewModel();
// Set some properties here
var context = new ValidationContext(sut, null, null);
var results = new List<ValidationResult>();
var isModelStateValid =Validator.TryValidateObject(sut, context, results, true);
// Assert here
}
2. 無効なモデル状態を持つコントローラ
[Test]
public void test_controller_with_model_error()
{
var controller = new PosController();
controller.ModelState.AddModelError("test", "test");
ActionResult result = posController.Index(new PosViewModel());
// Assert that the controller executed the right actions when the model is invalid
}
3. 有効なモデル状態を持つコントローラ
[Test]
public void test_controller_with_valid_model()
{
var controller = new PosController();
controller.ModelState.Clear();
ActionResult result = posController.Index(new PosViewModel());
// Assert that the controller executed the right actions when the model is valid
}