c# MVC如何测试自定义模型验证
本文关键字:自定义 模型 验证 测试 MVC 何测试 | 更新日期: 2023-09-27 18:07:23
我有一个名为:requiredIf的自定义属性。这个属性与自定义的DataAnnotationsModelValidator相关,名为RequiredIfValidator。
我在Global.asax.cs文件中声明了这个映射:
DataAnnotationsModelValidatorProvider.RegisterAdapter( typeof( RequiredIfAttribute ), typeof( RequiredIfValidator ) );
运行时运行正常:)
但是我想通过单元测试来验证我的模型。我猜我们有下面的
public class MyModel
{
public bool A {get;set;}
[RequiredIf ("A", true)]
public bool? B {get;set;}
}
当A为假时该模型有效,当A为真时B需要设置为真或假
我试着用下面的单元测试测试这个验证:
var viewModel = new MyModel();
var context = new ValidationContext( viewModel, null, null );
var results = new List<ValidationResult>();
viewModel.A = false;
var isModelStateValid = Validator.TryValidateObject( viewModel, context, results, true );
Assert.IsFalse( isModelStateValid );
断言失败。这是逻辑,因为我的RequiredIfValidator没有设置。所以我的问题是我如何设置这个自定义验证器来运行我的单元测试?
谢谢,
我设法使用以下扩展方法使其工作:
public static class ViewModelExtensions
{
public static IReadOnlyCollection<ValidationResult> GetValidationResults<T>(this T viewModel, Func<Type, object> serviceProvider = null)
{
var result = GetComponentValidationResults(viewModel, serviceProvider);
var modelValidationResults = GetModelValidationResults(viewModel);
return result
.Concat(modelValidationResults.ToValidationResults())
.ToList();
}
private static List<ValidationResult> GetComponentValidationResults<T>(T viewModel, Func<Type, object> serviceProvider)
{
var vc = new ValidationContext(viewModel);
if (serviceProvider != null)
{
vc.InitializeServiceProvider(serviceProvider);
}
var result = new List<ValidationResult>();
Validator.TryValidateObject(viewModel, vc, result, true);
return result;
}
private static IEnumerable<ModelValidationResult> GetModelValidationResults<T>(T model)
{
var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(T));
/* build a stub controller context */
var controllerContext = Fake.ControllerContext.Build();
var validator = ModelValidator.GetModelValidator(modelMetadata, controllerContext);
return validator.Validate(null);
}
private static IEnumerable<ValidationResult> ToValidationResults(this IEnumerable<ModelValidationResult> results)
{
return results.Select(r => r.ToValidationResult());
}
private static ValidationResult ToValidationResult(this ModelValidationResult result)
{
return new ValidationResult(result.Message, new[] {result.MemberName});
}
}
可以这样使用:
// arrange
var target = new MyViewModel();
// act
var actual = target.GetValidationResults(StubServiceProvider);
// assert
/* Assertions for whatever the expected validation failure might be */
注意:
-
Fake.ControllerContext.Build()
调用是一个工厂,它产生一个基于以下内容的存根控制器上下文:https://stackoverflow.com/a/32672/90609 - 我设法让这个工作为我的场景,我已经注册了RequiredAttribute自定义适配器。