如何使用AutoFixture自定义Contract类集合并按指定日期生成实例
解决方案
方法一:自定义扩展方法(简单直接)
你可以给Fixture写个扩展方法,传入指定日期后直接生成符合要求的Contract集合,逻辑清晰易维护:
public static class FixtureExtensions { public static IEnumerable<Contract> CreateContractsWithDateRange(this IFixture fixture, DateTime specifiedDate) { var pastDate = specifiedDate.AddDays(-1); var futureDate = specifiedDate.AddDays(1); return new List<Contract> { fixture.Build<Contract>().With(c => c.StartDate, pastDate).Create(), fixture.Build<Contract>().With(c => c.StartDate, specifiedDate).Create(), fixture.Build<Contract>().With(c => c.StartDate, futureDate).Create() }; } }
使用示例:
var fixture = new Fixture(); var targetDate = new DateTime(2024, 5, 1); var contracts = fixture.CreateContractsWithDateRange(targetDate);
方法二:实现ISpecimenBuilder(全局自定义样本生成)
如果需要通过AutoFixture默认请求流程(比如fixture.Create<IEnumerable<Contract>>())生成集合,可实现ISpecimenBuilder并结合种子值传递指定日期:
1. 自定义Builder实现
public class ContractRangeBuilder : ISpecimenBuilder { public object Create(object request, ISpecimenContext context) { var requestType = request as Type; // 仅处理Contract集合类型的请求 if (requestType == null || !typeof(IEnumerable<Contract>).IsAssignableFrom(requestType)) return new NoSpecimen(); // 获取传递的种子日期,无种子则用当前日期兜底 var seedDate = context.Resolve(new SeedRequest(typeof(DateTime), null)) as DateTime? ?? DateTime.Now; var pastDate = seedDate.AddDays(-1); var futureDate = seedDate.AddDays(1); return new List<Contract> { new Contract { StartDate = pastDate }, new Contract { StartDate = seedDate }, new Contract { StartDate = futureDate } }; } }
2. 注册并使用
var fixture = new Fixture(); fixture.Customizations.Add(new ContractRangeBuilder()); // 传入种子日期生成集合 var targetDate = new DateTime(2024, 5, 1); var contracts = fixture.Create<IEnumerable<Contract>>(targetDate);
注意事项
- 非全局需求优先用扩展方法,避免自定义Builder影响其他类型的默认生成逻辑
- 使用
ISpecimenBuilder时,需精准判断请求类型,防止误处理其他对象的生成请求
内容的提问来源于stack exchange,提问作者Complexity
相关产品推荐
相关产品推荐

