C# 如何测试属性是否具有必需的注释?
我对属性的定义如下:C# 如何测试属性是否具有必需的注释?,c#,.net,C#,.net,我对属性的定义如下: [Required(ErrorMessage="The Year of Manufacture has to be filled")] public int? YearOfManufacture { get; set; } 如果属性设置了所需的注释,我如何编写单元测试,哪些测试?您可以有一个测试助手方法,该方法将在视图模型的特定实例上运行验证: public bool TryValidate(object model, out ICollection<Validat
[Required(ErrorMessage="The Year of Manufacture has to be filled")]
public int? YearOfManufacture { get; set; }
如果属性设置了所需的注释,我如何编写单元测试,哪些测试?您可以有一个测试助手方法,该方法将在视图模型的特定实例上运行验证:
public bool TryValidate(object model, out ICollection<ValidationResult> results)
{
var context = new ValidationContext(model, serviceProvider: null, items: null);
results = new List<ValidationResult>();
return Validator.TryValidateObject(
model, context, results, validateAllProperties: true
);
}
public bool TryValidate(对象模型,out-ICollection结果)
{
var context=新的ValidationContext(模型,serviceProvider:null,items:null);
结果=新列表();
返回Validator.TryValidateObject(
模型、上下文、结果、验证所有属性:true
);
}
然后在单元测试中:
[TestMethod]
public void YearOfManufacture_Is_Required()
{
// arrange
var sut = new MyViewModel();
sut.YearOfManufacture = null;
ICollection<ValidationResult> results;
// act
var actual = TryValidate(sut, out results);
// assert
Assert.IsFalse(actual);
}
[TestMethod]
需要制造年的公开作废()
{
//安排
var sut=新的MyViewModel();
sut.YearOfManufacture=null;
i收集结果;
//表演
var实际值=TryValidate(sut,out结果);
//断言
Assert.IsFalse(实际);
}
除了使用DataAnnotation之外,您还可以看看它,它允许您以流畅的方式表达更复杂的验证规则,它有一个很好的方法,您的验证规则更简单。您可以有一个测试助手方法,可以在视图模型的特定实例上运行验证:
public bool TryValidate(object model, out ICollection<ValidationResult> results)
{
var context = new ValidationContext(model, serviceProvider: null, items: null);
results = new List<ValidationResult>();
return Validator.TryValidateObject(
model, context, results, validateAllProperties: true
);
}
public bool TryValidate(对象模型,out-ICollection结果)
{
var context=新的ValidationContext(模型,serviceProvider:null,items:null);
结果=新列表();
返回Validator.TryValidateObject(
模型、上下文、结果、验证所有属性:true
);
}
然后在单元测试中:
[TestMethod]
public void YearOfManufacture_Is_Required()
{
// arrange
var sut = new MyViewModel();
sut.YearOfManufacture = null;
ICollection<ValidationResult> results;
// act
var actual = TryValidate(sut, out results);
// assert
Assert.IsFalse(actual);
}
[TestMethod]
需要制造年的公开作废()
{
//安排
var sut=新的MyViewModel();
sut.YearOfManufacture=null;
i收集结果;
//表演
var实际值=TryValidate(sut,out结果);
//断言
Assert.IsFalse(实际);
}
除了使用DataAnnotations,您还可以看看它能让您以流畅的方式表达更复杂的验证规则,它有一个很好的功能,您的验证规则更容易。如果出于任何原因,您想测试一个属性是否被注释(而不是测试验证注释是否有效),您可以使用测试中建议的扩展方法:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property .GetCustomAttributes(attrType, false).FirstOrDefault();
}
public static T GetAttributeFrom(此对象实例,string propertyName),其中T:Attribute
{
var attrType=typeof(T);
var property=instance.GetType().GetProperty(propertyName);
return(T)property.GetCustomAttributes(attrType,false).FirstOrDefault();
}
编辑:
(1) 使用FirstOrDefault()而不是First()正确处理未注释的属性。
(2) @Pavel Straka:在下面添加了更多示例代码以回答Pavel Straka的评论
class Sample
{
[Required(ErrorMessage = "The Year of Manufacture has to be filled")]
public int? YearOfManufacture { get; set; }
public int? NotAttributedProperty { get; set; }
}
static class Annotations
{
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property.GetCustomAttributes(attrType, false).FirstOrDefault();
}
}
class Program
{
static void Main(string[] args)
{
var sampleInstance = new Sample();
var annotation = sampleInstance.GetAttributeFrom<RequiredAttribute>("YearOfManufacture");
var nullAnnotation = sampleInstance.GetAttributeFrom<RequiredAttribute>("NotAttributedProperty");
}
}
类示例
{
[必需(ErrorMessage=“必须填写制造年份”)]
公共整数?制造年份{get;set;}
public int?notAttribute属性{get;set;}
}
静态类注释
{
公共静态T GetAttributeFrom(此对象实例,字符串propertyName),其中T:Attribute
{
var attrType=typeof(T);
var property=instance.GetType().GetProperty(propertyName);
return(T)property.GetCustomAttributes(attrType,false).FirstOrDefault();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var sampleInstance=新样本();
var annotation=sampleInstance.GetAttributeFrom(“制造年份”);
var nullAnnotation=sampleInstance.GetAttributeFrom(“notAttributeProperty”);
}
}
如果出于任何原因,您希望测试某个属性是否被注释(而不是测试验证注释是否有效),您可以使用测试中建议的扩展方法:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property .GetCustomAttributes(attrType, false).FirstOrDefault();
}
public static T GetAttributeFrom(此对象实例,string propertyName),其中T:Attribute
{
var attrType=typeof(T);
var property=instance.GetType().GetProperty(propertyName);
return(T)property.GetCustomAttributes(attrType,false).FirstOrDefault();
}
编辑:
(1) 使用FirstOrDefault()而不是First()正确处理未注释的属性。
(2) @Pavel Straka:在下面添加了更多示例代码以回答Pavel Straka的评论
class Sample
{
[Required(ErrorMessage = "The Year of Manufacture has to be filled")]
public int? YearOfManufacture { get; set; }
public int? NotAttributedProperty { get; set; }
}
static class Annotations
{
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property.GetCustomAttributes(attrType, false).FirstOrDefault();
}
}
class Program
{
static void Main(string[] args)
{
var sampleInstance = new Sample();
var annotation = sampleInstance.GetAttributeFrom<RequiredAttribute>("YearOfManufacture");
var nullAnnotation = sampleInstance.GetAttributeFrom<RequiredAttribute>("NotAttributedProperty");
}
}
类示例
{
[必需(ErrorMessage=“必须填写制造年份”)]
公共整数?制造年份{get;set;}
public int?notAttribute属性{get;set;}
}
静态类注释
{
公共静态T GetAttributeFrom(此对象实例,字符串propertyName),其中T:Attribute
{
var attrType=typeof(T);
var property=instance.GetType().GetProperty(propertyName);
return(T)property.GetCustomAttributes(attrType,false).FirstOrDefault();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var sampleInstance=新样本();
var annotation=sampleInstance.GetAttributeFrom(“制造年份”);
var nullAnnotation=sampleInstance.GetAttributeFrom(“notAttributeProperty”);
}
}
我建议您这样做,这样您就可以非常干净地执行此操作:
typeof(MyType)
.GetProperty("YearOfManufacture")
.Should()
.BeDecoratedWith<RequiredAttribute>("because MyType.YearOfManufacture is required.");
typeof(MyType)
.GetProperty(“制造年份”)
.Should()
.BeDecoratedWith(“因为需要MyType.YearOfManufacture.”);
我建议您这样做,这样您就可以非常干净地执行此操作:
typeof(MyType)
.GetProperty("YearOfManufacture")
.Should()
.BeDecoratedWith<RequiredAttribute>("because MyType.YearOfManufacture is required.");
typeof(MyType)
.GetProperty(“制造年份”)
.Should()
.BeDecoratedWith(“因为需要MyType.YearOfManufacture.”);
如果没有它会发生什么?让它发生并检查它。这就是你要找的吗?为此编写单元测试有什么意义?是否接受这些答案中的任何一个?如果没有,会发生什么?让它发生并检查它。这就是你要找的吗?为此编写单元测试有什么意义?是否接受这些答案中的任何一个?您也可以通过调用MyController.Validate(sut)
来使用控制器。您还可以通过调用