C# 如何让Autofixture创建包含接口类型属性的类型实例?
我有这样一门课:C# 如何让Autofixture创建包含接口类型属性的类型实例?,c#,autofixture,test-data,C#,Autofixture,Test Data,我有这样一门课: public class ViewModel { public IPagination<Data> List { get; set; } // interface! public SearchFilter SearchFilter { get; set; } public string Test { get; set; } } public class SearchFilter { public string Name { get;
public class ViewModel
{
public IPagination<Data> List { get; set; } // interface!
public SearchFilter SearchFilter { get; set; }
public string Test { get; set; }
}
public class SearchFilter
{
public string Name { get; set; }
}
一种简单的可能性是注册工厂方法:
fixture.Register<YourInterface>(() => new InterfaceImpl());
理论上,应该可以填充自动模拟实例的属性 假设
ViewModel
类型的IPagination
属性定义为:
public interface IPagination<T>
{
SearchFilter Property1 { get; set; }
string Property2 { get; set; }
}
然后,以下调用将创建ViewModel
(仅在运行时已知)的实例,提供IPagination的自动模拟实例,并为属性赋值。
var value = context.Resolve(typeof(ViewModel));
// List -> {IPagination`1Proxy593314cf4c134c5193c0019045c05a80}
// List.Property1.Name -> "Namef71b8571-a1a0-421d-9211-5048c96d891b"
// List.Property2 -> "f58cae65-b704-43ec-b2ce-582a5e6177e6"
MyCustomization
在应用此定制之前,请记住,这只适用于此特定场景(因此描述中的特殊场景)。我强烈建议使用其中一个用于自动模拟的扩展,或其他任何地方
内部类MyCustomization:ICCustomization
{
公共空间自定义(iTexture装置)
{
fixture.Customizations.Add(新的MySpecimenBuilder());
}
私有类MySpecimenBuilder:ISpecimenBuilder
{
公共对象创建(对象请求,ISPecementContext上下文)
{
var type=请求类型;
if(type==null | |!type.IsInterface)
{
返回新的NoSpecimen(请求);
}
对象样本=此
.GetType()
.GetMethod(
“创建”,
BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(新[]{type})
.Invoke(这个新对象[]{context});
返回样本;
}
私有静态对象创建(ISpecimenContext上下文)
特雷奎斯特:课堂在哪里
{
var mock=new mock();
mock.SetupAllProperties();
foreach(PropertyInfo-propInfo类型为(TRequest.GetProperties())
{
对象值=context.Resolve(propInfo.PropertyType);
propInfo.SetValue(mock.Object,value);
}
返回mock.Object;
}
}
}
视图模型和上一个问题的答案与问题的最后一句有什么关系?请关注您的问题。您是对的,我脑子里有这么多问题:)是否也可以让Autofixture围绕接口创建一个动态代理并用测试数据填充它?是否可以用数据填充创建的代理列表?调用mock.SetupAllProperties()不是更容易一点吗
?使实现更加简单。下面介绍如何配置以设置所有模拟实例以及自动填充其属性。
public interface IPagination<T>
{
SearchFilter Property1 { get; set; }
string Property2 { get; set; }
}
var fixture = new Fixture()
.Customize(new MyCustomization());
var context = new SpecimenContext(fixture.Compose());
var value = context.Resolve(typeof(ViewModel));
// List -> {IPagination`1Proxy593314cf4c134c5193c0019045c05a80}
// List.Property1.Name -> "Namef71b8571-a1a0-421d-9211-5048c96d891b"
// List.Property2 -> "f58cae65-b704-43ec-b2ce-582a5e6177e6"
internal class MyCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new MySpecimenBuilder());
}
private class MySpecimenBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var type = request as Type;
if (type == null || !type.IsInterface)
{
return new NoSpecimen(request);
}
object specimen = this
.GetType()
.GetMethod(
"Create",
BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(new[] { type })
.Invoke(this, new object[] { context });
return specimen;
}
private static object Create<TRequest>(ISpecimenContext context)
where TRequest : class
{
var mock = new Mock<TRequest>();
mock.SetupAllProperties();
foreach (PropertyInfo propInfo in typeof(TRequest).GetProperties())
{
object value = context.Resolve(propInfo.PropertyType);
propInfo.SetValue(mock.Object, value);
}
return mock.Object;
}
}
}