LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

.NET单元测试使用AutoFixture按需填充的几种方式和最佳实践

freeflydom
2024年7月22日 10:29 本文热度 750

AutoFixture是一个.NET库,旨在简化单元测试中的数据设置过程。通过自动生成测试数据,它帮助开发者减少测试代码的编写量,使得单元测试更加简洁、易读和易维护。AutoFixture可以用于任何.NET测试框架,如xUnit、NUnit或MSTest。

默认情况下AutoFixture生成的字段值很多时候都满足不了测试需求,比如:

public class User

{

public int Id { get; set; }

public string Name { get; set; } = null!;

[EmailAddress]

public string? Email { get; set; }

[StringLength(512)]

public string? Address { get; set; }

public DateTime CreatedAt { get; set; } = DateTime.Now;

}

如果直接使用 Create<T>()生成的User对象,他会默认给你填充Id为随机整数,Name和Email为一串Guid,显然这里的邮箱地址生成就不能满足要求,并不是一个有效的邮箱格式

那么如何让AutoFixture按需生成有效的测试数据呢?方法其实有好几种:

方法1:直接定制

var fixture = new Fixture();

fixture.Customize<User>(c => c

    .With(x => x.Email, "特定值")

    .Without(x => x.Id));

这里,With方法用于指定属性的具体值,而Without方法用于排除某些属性不被自动填充。

方法2:使用匿名函数

这在需要对生成的数据进行更复杂的操作时非常有用。

var fixture = new Fixture();

fixture.Customize<User>(c => c.FromFactory(() => new User

{

    Email = "通过工厂方法生成",

}));

方法3:实现ICustomization接口

对于更复杂的定制需求,可以通过实现ICustomization接口来创建一个定制化类。这种方法的好处是可以重用定制逻辑,并且使得测试代码更加整洁。

public class MyCustomClassCustomization : ICustomization

{

    public void Customize(IFixture fixture)

    {

        fixture.Customize<User>(c => c

            .With(x => x.Email, "自定义值")

            .Without(x => x.Id));

    }

}

// 使用定制化

var fixture = new Fixture();

fixture.Customize(new MyCustomClassCustomization());

方法4:使用Build<T>方法

Build<T>方法提供了一种链式调用的方式来定制类型的生成规则,这在只需要对单个对象进行简单定制时非常方便。

var myCustomObject = fixture.Build<User>()

                            .With(x => x.Email, $"{Guid.NewId()}@example.com")

                            .Without(x => x.Id)

                            .Create();

最佳实践:

这里以xunit测试框架为例,
我们需要提前引用AutoFixture,AutoFixture.Xunit2库,实现一个UserAutoDataAttribute类,继承自InlineAutoDataAttribute 重写GetData方法,大致代码如下:

public  class UserAutoDataAttribute : InlineAutoDataAttribute

    {

        public UserAutoDataAttribute(params object[] values) : base(values)

        {

            ArgumentNullException.ThrowIfNull(values[0]);

        }


        public override IEnumerable<object[]> GetData(MethodInfo testMethod)

        {

            var fixture = new Fixture();

            //这里使用上面的4种方式的一种,亦或者根据自身情况定制!

            var user = fixture.Build<User>()

                 //.With(x => x.Id, 0)

                 .Without(x => x.Id) //ID需要排除因为EFCore需要插入时自动生成

                 .With(x => x.Email, $"{Uuid7.NewUuid7()}@example.com") //邮箱地址,需要照规则生成

                 .Create();

            yield return new object[] { Values[0], user };

        }

    }

下面是一个测试用例,需要填充db,和一个自动生成的User参数

public class UnitOfWorkTests(ITestOutputHelper output)

{

[Theory]

[UserAutoData(1)]

[UserAutoData(2)]

public async Task MyUnitOfWorkTest(int db, User user)

{

var services = new ServiceCollection();

services.AddLogging();

services.AddDbContext<TestDbContext>(options =>

{

                    options.UseInMemoryDatabase($"test-{db}");

});

services.AddUnitOfWork<TestDbContext>();


var provider = services.BuildServiceProvider();

var uow = provider.GetRequiredService<IUnitOfWork<TestDbContext>>();


//add user

await uow.GetRepository<User>().InsertAsync(user);

await uow.SaveChangesAsync();


// select user

var user2 = await uow.GetRepository<User>().FindAsync(1);

Assert.NotNull(user2);


// delete user

uow.GetRepository<User>().Delete(1);

var row = await uow.SaveChangesAsync();


Assert.Equal(1, row);


// select user

user2 = await uow.GetRepository<User>().GetFirstOrDefaultAsync(x => x.Id == 1);

Assert.Null(user2);

}

}

如果你已经习惯编写单元测试,但还没有使用AutoFixture,那么推荐你尝试一下,也许你也会喜欢上TA

转自https://www.cnblogs.com/vipwan/p/18311419 作者万雅虎


该文章在 2024/7/22 10:29:20 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved