一款开源、强大、简单易用的 .NET 假数据生成利器

前言

在日常的 .NET 项目开发中,我们经常需要大量的测试数据来验证业务逻辑、填充数据库、进行性能测试或者做产品演示。手动编写这些测试数据不仅枯燥乏味、浪费时间,而且难以覆盖各种边界场景。今天大姚给大家推荐一款开源、强大、简单易用的 .NET 假数据生成库:Bogus

项目介绍

Bogus 是一个基于著名的 faker.js 移植而来的开源(MIT License) .NET 假数据生成库,它为 .NET 开发者提供了一套强大、简单易用的 API,可快速生成各种类型的模拟数据,支持 40+ 种语言区域本地化,广泛应用于单元测试、数据库填充、原型演示以及示例数据生成等场景。

支持语言

支持语言:C#、F#、VB.NET

应用场景

  • 单元测试 / 集成测试:快速生成符合业务模型的测试对象,替代手工 Mock 数据。
  • 数据库填充(Seed) :开发/测试环境数据库填充真实感十足的假数据。
  • 性能与压力测试:批量生成大规模数据集来模拟真实负载。
  • API 开发调试:快速构造 API 返回的模拟响应数据。
  • 数据脱敏:替换生产数据中的敏感信息。

支持以下语言环境

Bogus 支持以下语言环境:

创建一个 .NET 控制台应用

接下来我们创建一个名为:BogusExercise .NET 9 控制台应用:

项目 NuGet 安装

在 NuGet 包管理器控制台中执行:

复制代码
Install-Package Bogus

或者在 NuGet 包管理器中搜索安装:

Bogus 快速入门

生成 3 个随机订单的模拟用户信息

以下是 Bogus 仓库中提供的示例代码,使用 Bogus 生成了 3 个带随机订单的模拟用户。

dart 复制代码
    public class Program
    {
        static void Main(string[] args)
        {
            //生成 3 个随机订单的模拟用户信息
            var users = GenerateSampleUsers(3);
        }

        /// <summary>
        /// 生成随机订单的模拟用户
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        public static List<User> GenerateSampleUsers(int count = 3)
        {
            // 设置随机种子,生成可重复的数据集
            Randomizer.Seed = new Random(3897234);

            var fruit = new[] { "apple", "banana", "orange", "strawberry", "kiwi" };

            var orderIds = 0;
            var testOrders = new Faker<Order>()
                // 开启严格模式:确保所有属性都有规则
                .StrictMode(true)
                // OrderId 自增
                .RuleFor(o => o.OrderId, f => orderIds++)
                // 从水果篮中随机挑选
                .RuleFor(o => o.Item, f => f.PickRandom(fruit))
                // 随机数量 1~10
                .RuleFor(o => o.Quantity, f => f.Random.Number(1, 10))
                // 可空 int?,80% 概率为 null
                .RuleFor(o => o.LotNumber, f => f.Random.Int(0, 100).OrNull(f, .8f));

            var userIds = 0;
            var testUsers = new Faker<User>()
                // 自定义构造函数
                .CustomInstantiator(f => new User(userIds++, f.Random.Replace("###-##-####")))
                // 基本规则
                .RuleFor(u => u.FirstName, f => f.Name.FirstName())
                .RuleFor(u => u.LastName, f => f.Name.LastName())
                .RuleFor(u => u.Avatar, f => f.Internet.Avatar())
                .RuleFor(u => u.UserName, (f, u) => f.Internet.UserName(u.FirstName, u.LastName))
                .RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName))
                .RuleFor(u => u.SomethingUnique, f => $"Value {f.UniqueIndex}")
                .RuleFor(u => u.SomeGuid, Guid.NewGuid)
                // 随机选取枚举
                .RuleFor(u => u.Gender, f => f.PickRandom<Gender>())
                .RuleFor(u => u.CartId, f => Guid.NewGuid())
                // 组合属性:利用已生成的 FirstName 和 LastName
                .RuleFor(u => u.FullName, (f, u) => u.FirstName + " " + u.LastName)
                // 嵌套集合生成
                .RuleFor(u => u.Orders, f => testOrders.Generate(3))
                // 生成完成后的回调
                .FinishWith((f, u) =>
                {
                    Console.WriteLine("User Created! Name={0}", u.FullName);
                });

            // 一次生成 3 个用户
            return testUsers.Generate(count);
        }
    }

    /// <summary>
    /// 订单实体
    /// </summary>
    public class Order
    {
        public int OrderId { get; set; }
        public string Item { get; set; }
        public int Quantity { get; set; }
        public int? LotNumber { get; set; }
    }

    /// <summary>
    /// 性别枚举
    /// </summary>
    public enum Gender
    {
        Male,
        Female
    }

    /// <summary>
    /// 用户实体
    /// </summary>
    public class User
    {
        public User(int userId, string ssn)
        {
            this.Id = userId;
            this.SSN = ssn;
        }

        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public string SomethingUnique { get; set; }
        public Guid SomeGuid { get; set; }
        public string Avatar { get; set; }
        public Guid CartId { get; set; }
        public string SSN { get; set; }
        public Gender Gender { get; set; }
        public List<Order> Orders { get; set; }
    }

生成随机用户信息

使用 Bogus 快速生成随机用户姓名、邮箱、地址、电话等关联数据:

csharp 复制代码
        /// <summary>
        /// 生成随机用户信息
        /// </summary>
        public static void GenerateRandomData()
        {
            // 自动生成姓名、邮箱、地址、电话等关联数据
            var faker = new Faker("zh_CN");// 使用简体中文
            var randomName = faker.Name.FullName();
            var randomEmail = faker.Internet.Email();
            var randomAddress = faker.Address.FullAddress();
            var randomPhone = faker.Phone.PhoneNumber();
            Console.WriteLine($"Name: {randomName}");
            Console.WriteLine($"Email: {randomEmail}");
            Console.WriteLine($"Address: {randomAddress}");
            Console.WriteLine($"Phone: {randomPhone}");
        }

EF Core 数据库种子数据填充

使用 EF Core 填充 Blog & Post 数据:

csharp 复制代码
    /// <summary>
    /// EF Core 数据库种子数据填充
    /// 适合开发/测试环境,在应用启动时自动填充数据:
    /// FakeData.Init(10); // 生成 10 个 Blog,每个包含 3~5 篇 Post
    /// </summary>
    public static class FakeData
    {
        public static List<Blog> Blogs = new List<Blog>();
        public static List<Post> Posts = new List<Post>();

        public static void Init(int count)
        {
            var postId = 1;
            var postFaker = new Faker<Post>()
                .RuleFor(p => p.PostId, _ => postId++)
                .RuleFor(p => p.Title, f => f.Hacker.Phrase())
                .RuleFor(p => p.Content, f => f.Lorem.Sentence());

            var blogId = 1;
            var blogFaker = new Faker<Blog>()
                .RuleFor(b => b.BlogId, _ => blogId++)
                .RuleFor(b => b.Url, f => f.Internet.Url())
                .RuleFor(b => b.Posts, (f, b) =>
                {
                    postFaker.RuleFor(p => p.BlogId, _ => b.BlogId);
                    var posts = postFaker.GenerateBetween(3, 5);

                    // 关键:收集所有 Posts 到静态列表中
                    Posts.AddRange(posts);

                    return posts;
                });

            // 清空旧数据,避免重复调用累积
            Blogs.Clear();
            Posts.Clear();

            Blogs = blogFaker.Generate(count);
        }
    }

    /// <summary>
    /// Blog
    /// </summary>
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public List<Post> Posts { get; set; }
    }

    /// <summary>
    /// Post
    /// </summary>
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public int BlogId { get; set; }
    }

在 Program.cs 启动时填充:

ini 复制代码
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // 注册 DbContext
            builder.Services.AddDbContext<BlogDbContext>(options =>
                options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

            var app = builder.Build();

            // 应用启动时填充种子数据
            using (var scope = app.Services.CreateScope())
            {
                var context = scope.ServiceProvider.GetRequiredService<BlogDbContext>();

                // 确保数据库已创建
                context.Database.EnsureCreated();

                // 仅在数据库为空时填充假数据
                if (!context.Blogs.Any())
                {
                    FakeData.Init(10); // 生成 10 个 Blog,每个包含 3~5 篇 Post

                    context.Blogs.AddRange(FakeData.Blogs);
                    context.Posts.AddRange(FakeData.Posts);
                    context.SaveChanges();

                    Console.WriteLine($"已填充 {FakeData.Blogs.Count} 个博客, {FakeData.Posts.Count} 篇文章");
                }
            }

            app.MapControllers();
            app.Run();
        }
    }

自定义扩展 Bogus 数据集

开发者可以轻松扩展 Bogus,添加自定义的数据生成器:

csharp 复制代码
    /// <summary>
    /// 为 Bogus 的 Faker 类提供食品相关的自定义假数据扩展方法
    /// </summary>
    public static class FoodExtensions
    {
        /// <summary>
        /// 生成一个随机的糖果名称
        /// </summary>
        /// <param name="faker"></param>
        /// <returns></returns>
        public static string Candy(this Faker faker)
        {
            return faker.PickRandom(new[] { "巧克力", "棒棒糖", "口香糖", "软糖", "太妃糖" });
        }

        /// <summary>
        /// 生成一个随机的饮品名称
        /// </summary>
        /// <param name="faker"></param>
        /// <returns></returns>
        public static string Drink(this Faker faker)
        {
            return faker.PickRandom(new[] { "可乐", "雪碧", "橙汁", "咖啡", "牛奶" });
        }
    }
    
    // 使用自定义扩展
    var faker = new Faker();
    Console.WriteLine($"最爱糖果: {faker.Candy()}");
    Console.WriteLine($"最爱饮料: {faker.Drink()}");

项目源码地址

更多项目实用功能和特性欢迎前往项目开源地址查看👀,别忘了给项目一个Star支持💖。

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没🤞)。

相关推荐
青云计划8 小时前
知光项目知文发布模块
java·后端·spring·mybatis
Victor3568 小时前
MongoDB(9)什么是MongoDB的副本集(Replica Set)?
后端
Victor3568 小时前
MongoDB(8)什么是聚合(Aggregation)?
后端
yeyeye11110 小时前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
Tony Bai10 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php
+VX:Fegn089511 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
程序猿阿伟11 小时前
《GraphQL批处理与全局缓存共享的底层逻辑》
后端·缓存·graphql
小小张说故事11 小时前
SQLAlchemy 技术入门指南
后端·python
识君啊11 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端
想用offer打牌12 小时前
MCP (Model Context Protocol) 技术理解 - 第五篇
人工智能·后端·mcp