[英]How to generate instance with fixed value for certain property?
We use AutoFixture for test data generation, one of the scenarios requires us to provide fixed data, so we can test the method below.我们使用 AutoFixture 进行测试数据生成,其中一种场景需要我们提供固定数据,所以我们可以测试下面的方法。
public enum OrderState { Initial = 0, State1 = 1, State2 = 2, State3 = 3 };
public record Order(Guid Id, string Reference, OrderState State);
public static class Filter
{
public static IEnumerable<Order> ByState(IEnumerable<Order> orders, OrderState state)
{
return orders.Where(order => order.State == state);
}
}
Test测试
[Fact]
public void Returns_only_orders_with_initial_state()
{
// Arrange
var fixture = new Fixture();
var order1 = fixture.Build(o => o.State, OrderState.Initial).Create();
var allOrders = new[]
{
fixture.Build(o => o.State, OrderState.State1).Create(),
fixture.Build(o => o.State, OrderState.State2).Create(),
fixture.Build(o => o.State, OrderState.State3).Create(),
order1
};
// Act
var actual = new Filter().ByState(allOrders, OrderState.Initial);
// Assert
actual.Should().BeEquivalentTo(new[] { order1 });
}
Test fails because AutoFixture can not write to readonly properties - I understand that.测试失败,因为 AutoFixture 无法写入只读属性 - 我明白这一点。
How can I create an instance with fixed value for the State
property, but still use "random" values for other properties?如何为
State
属性创建具有固定值的实例,但仍对其他属性使用“随机”值?
You can achieve this using AutoFixture's SpecimenBuilder
facility.您可以使用 AutoFixture 的
SpecimenBuilder
工具来实现这一点。
An example of his can be found in this post他的一个例子可以在这篇文章中找到
A demonstration for your use case:您的用例的演示:
using AutoFixture.Kernel;
using System.Reflection;
namespace Example
{
public enum OrderState { Initial = 0, State1 = 1, State2 = 2, State3 = 3 };
public record Order(Guid Id, string Reference, OrderState State);
public class OrderStateArg : ISpecimenBuilder
{
private readonly OrderState _state;
public OrderStateArg(OrderState state)
{
_state = state;
}
public object Create(object request, ISpecimenContext context)
{
var pi = request as ParameterInfo;
if (pi == null)
{
return new NoSpecimen();
}
if (pi.Member.DeclaringType != typeof(Order) ||
pi.ParameterType != typeof(OrderState) ||
pi.Name != "State")
{
return new NoSpecimen();
}
return _state;
}
}
public static class Filter
{
public static IEnumerable<Order> ByState(IEnumerable<Order> orders, OrderState state)
{
return orders.Where(order => order.State == state);
}
}
public class Class1
{
[Fact]
public void Returns_only_orders_with_initial_state()
{
var fixture = new Fixture();
fixture.Customizations.Add(new OrderStateArg(OrderState.Initial));
var order1 = fixture.Create<Order>();
fixture.Customizations.Clear();
var allOrders = new Order[]
{
fixture.Create<Order>(),
fixture.Create<Order>(),
fixture.Create<Order>(),
order1
};
// Act
// Note on your original code, Filter is a static class
// so calling its methods do not require the new keyword.
var actual = Filter.ByState(allOrders, OrderState.Initial);
// Assert
actual.Should().BeEquivalentTo(new[] { order1 });
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.