微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AutoFixture - 创建“有效”和“无效”实例和 [AutoData]

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

解决方法

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

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

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

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

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

注意:我真的建议您使用第一种方法,因为它使输入数据无效的方式一目了然,并使断言结果更容易。

,

我可能会忽略 automapper 并创建一个类来负责创建测试所需的不同类型(无效或有效)的对象:

枚举.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;
        }
    }

这允许我以下列方式调用该类:

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?