AutoFixture - 创建 "Valid" 和 "Invalid" 实例和 [AutoData]

AutoFixture - Creation of "Valid" and "Invalid" instances and [AutoData]

我创建了以下示例模型:

internal sealed class Bike : IVehicle
{
    public Bike(
        Engine engineType,
        WindowHue windowHue,
        Vehicle transport,
        ushort wheelsCount,
        string name) =>
        (EngineType, WindowHue, Transport, WheelsCount, Name) =
        (engineType, windowHue, transport, wheelsCount, name);

    public WindowHue WindowHue { get; }
    public Engine EngineType { get; }
    public Vehicle Transport { get; }
    public ushort WheelsCount { get; }
    public string Name { get; }
}

我目前正在为 Bike 验证器编写单元测试,我想使用 AutoFixture 创建 Bike class 的实例,这些实例具有被认为有效和无效的值。有没有办法指示 AutoFixture 如何创建这些类型的实例并告诉它根据 运行 的单元测试获取有效或无效的实例?例如:在检查 Bike class 的有效实例是否通过验证的测试用例中,我希望 AutoFixture 创建一个有效的 Bike 实例。 我试图通过创建自定义标本生成器来实现此行为,但似乎最后一个注册的生成器用于创建请求类型的实际实例。另一个想法是创建构建器 class,它将使用 AutoFixture [通过“Create”方法]创建有效和无效的实例,并在测试用例中使用它,但我认为这不是一个好主意,因为它会导致创建冗余代码 [每个测试模型的构建器 class]。 如果上述行为是可能的,那么有没有办法通过使用 [AutoData] 属性来创建这样的实例,这样我就不必在测试用例主体中调用 AutoFixture?

我可能会将自动映射器排除在外,并创建一个 class 来负责创建测试所需的不同类型(无效或有效)的对象:

Enums.cs

    public enum BikeType
    {
        Valid,
        Invalid
    }

BikeCreator.cs

    public static class BikeCreator
    {
        private Bike CreateValidBike()
        {
            return new Bike() //make this object "valid"
        }

        private Bike CreateInvalidBike()
        {
            return new Bike(); //make this object "invalid"
        }

        public Bike CreateInstance(BikeType bikeType)
        {
            Bike bike = null;

            switch (bikeType)
            {
                case BikeType.Valid:
                    user = CreateValidBike();
                    break;
                case BikeType.Invalid:
                    user = CreateInvalidBike();
                    break;

            };

            return bike;
        }
    }

这让我可以通过以下方式调用 class:

//arrange
var invalidBike = BikeCreator.CreateInstance(BikeType.Invalid);
var validBike = BikeCreator.CreateInstance(BikeType.Valid);

这可能是一个很好的样板文件,可以重构为具有接口和泛型的更花哨的东西。有时“过早的优化是万恶之源”

可以,但是设置代码的复杂性将取决于域的复杂性。

您可以声明一个自定义,该自定义将使用有效数据构建您的 DTO 模型,然后通过自定义 [AutoData] 属性使用它,并在测试中使用 [=11= 使用无效数据自定义一些 DTO ] 或 .Build<T>().

现在,如果您想从测试参数中提供无效的 DTO,您可以尝试实现一个 [Invalid] 属性,这将自定义各个测试参数,然后使用 [Frozen] 来使用中的值其他生成的模型。

对于 [Invalid] 属性,您可以实现 AutoFixture.NUnit3 包中的 CustomizeAttributeAutoFixture.

中的 IParameterCustomizationSource

正如您将看到的自定义属性的输出是一个 ICustomization 意思在属性内部您可能有一个字典根据参数类型输出无效实体的自定义。

注意:我真的建议您使用第一种方法,因为它可以清楚地表明输入数据的无效方式,并使断言结果更容易。