Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

这篇具有很好参考价值的文章主要介绍了Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

上一章我们介绍了在xUnit单元测试中用xUnit.DependencyInject来使用依赖注入,上一章我们的Sample.Repository仓储层有一个批量注入的接口没有做单元测试,今天用这个示例来演示一下如何用Bogus创建模拟数据 ,和 EFCore 的种子数据生成

Bogus 的优势

  1. 丰富的数据生成支持:Bogus 提供了广泛的 API 支持,涵盖了各种数据类型和用例,使得生成虚假数据变得非常灵活和方便。

  2. 重复性和可控性:通过设置种子值,可以确保生成的虚假数据是可重复的,这对于需要一致的测试数据或示例数据非常有用。

  3. 易于使用:Bogus 使用流畅的语法和简单的方法调用,使得生成虚假数据变得简单直观,即使是对库不熟悉的用户也可以快速上手。

  4. 内置规则和语义:内置了许多常见数据类别的规则和语义,例如公司名称、产品名称、地址等,可以快速生成符合实际场景的数据。

  5. 灵活性:除了内置规则外,还可以通过自定义规则来生成特定的数据,满足不同场景下的需求。

  6. 社区支持:Bogus 是一个受欢迎的开源库,拥有活跃的社区支持和维护,可以获得持续的更新和改进。

Bogus 实战

简介

Bogus 是一个简单的.NET 语言(如 C#F#VB.NET)的假数据生成器。Bogus 本质上是 faker.jsC#移植版本,并受到 FluentValidation 的语法糖的启发。

使用

创建新的xUnit测试项目dotNetParadise.Bogus

Nuget包安装Bogus

Install-Package Bogus


创建一个`Bogus`帮助类
```c#
using Bogus;
using Sample.Repository.Models;

namespace dotNetParadise.Bogus
{
    public class BogusHelper
```package manager
PM> NuGet\Install-Package Bogus -Version 35.5.0

和上一篇的配置一样,测试项目需要添加仓储层的项目引用,并通过Nuget安装xUnit.DependencyInject,配置Startup

先看一下我们的Staff实体

public class Staff
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int? Age { get; set; }
    public List<string>? Addresses { get; set; }
    public DateTimeOffset? Created { get; set; }
}

接下来对我们批量新增的接口进行单元测试,测试数据通过Bogus生成,先看使用在讲解用法。

生成500条测试数据保存到 DB

[Fact]
public async Task BatchAddStaffAsync_WhenCalled_ShouldAddStaffToDatabase()
{
    // Arrange
    var staffs = new Faker<Staff>()
        .RuleFor(u => u.Name, f => f.Person.FullName)
        .RuleFor(u => u.Email, f => f.Person.Email)
        .RuleFor(u => u.Age, f => f.Random.Number(18, 60))
        .RuleFor(u => u.Addresses, f => f.MakeLazy(f.Random.Number(1, 3), () => f.Address.FullAddress()))
        .RuleFor(u => u.Created, f => f.Date.PastOffset())
        .Generate(500);

    // Act
    await _staffRepository.BatchAddStaffAsync(staffs, CancellationToken.None);

    // Assert
    var retrievedStaffs = await _staffRepository.GetAllStaffAsync(CancellationToken.None);
    Assert.NotNull(retrievedStaffs); // 确保 Staff 已成功添加到数据库
    Assert.Equal(500, retrievedStaffs.Count); // 确保正确数量的 Staff 已添加到数据库
    Assert.True(staffs.All(x => retrievedStaffs.Any(_ => x.Id == _.Id)));
}

看代码配置跟FluentValidation都是一样都是通过RuleFor来配置实体的属性

看一下生成的测试数据

Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

Run Tests

Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

单元测试成功,有了Bogus之后我们创建一些测试数据就方便多了

Bogus 的用法

locales 国际化

Bogus 支持许多不同的地区设置(locales),这些地区设置可用于生成特定语言或地区的虚假数据。您可以通过设置不同的 locale 参数来使用不同的地区设置。

Bogus 支持以下地区设置(locales

Locale Code Language Locale Code Language
af_ZA Afrikaans fr_CH French (Switzerland)
ar Arabic ge Georgian
az Azerbaijani hr Hrvatski
cz Czech id_ID Indonesia
de German it Italian
de_AT German (Austria) ja Japanese
de_CH German (Switzerland) ko Korean
el Greek lv Latvian
en English nb_NO Norwegian
en_AU English (Australia) ne Nepalese
en_AU_ocker English (Australia Ocker) nl Dutch
en_BORK English (Bork) nl_BE Dutch (Belgium)
en_CA English (Canada) pl Polish
en_GB English (Great Britain) pt_BR Portuguese (Brazil)
en_IE English (Ireland) pt_PT Portuguese (Portugal)
en_IND English (India) ro Romanian
en_NG Nigeria (English) ru Russian
en_US English (United States) sk Slovakian
en_ZA English (South Africa) sv Swedish
es Spanish tr Turkish
es_MX Spanish (Mexico) uk Ukrainian
fa Farsi vi Vietnamese
fi Finnish zh_CN Chinese
fr French zh_TW Chinese (Taiwan)
fr_CA French (Canada) zu_ZA Zulu (South Africa)

有些地区设置可能没有完整的数据集,比如说,有些语言可能缺少某些数据集,例如中文(zh_CN)可能没有 lorem 数据集,但韩语(ko)有。在这种情况下,Bogus 会默认使用英文(en)的数据集。换句话说,如果找不到特定语言的数据集,就会退而使用英文的数据集。如果您有兴趣帮助贡献新的地区设置或更新现有的设置,请查看我们的创建地区设置页面获取更多信息。

来验证一下

    [Theory]
    [InlineData(null)]
    [InlineData("zh_CN")]
    public void Locales_ConfigTest(string? locale)
    {
        //default
        var faker = locale is null ? new Faker<Staff>() : new Faker<Staff>(locale);

        faker.RuleFor(u => u.Name, f => f.Person.FullName)
            .RuleFor(u => u.Email, f => f.Person.Email)
            .RuleFor(u => u.Age, f => f.Random.Number(18, 60))
            .RuleFor(u => u.Addresses, f => f.MakeLazy(f.Random.Number(1, 3), () => f.Address.FullAddress()).ToList())
            .RuleFor(u => u.Created, f => f.Date.PastOffset());
        var staff = faker.Generate();
        var consoleType = locale is null ? "default" : locale;
        testOutputHelperAccessor.Output?.WriteLine($"{consoleType}:{JsonConvert.SerializeObject(staff)}");
    }

OutPut

  default:{"Id":0,"Name":"Clyde Price","Email":"Clyde17@yahoo.com","Age":39,"Addresses":["46277 Abraham Parkways, South Spencerland, Guadeloupe","6470 Porter Island, Lesliehaven, Chad","10804 Halvorson Brook, Ninaton, Iran"],"Created":"2023-04-30T11:31:35.5106219+08:00"}
    zh_CN:{"Id":0,"Name":"昊焱 尹","Email":"_82@yahoo.com","Age":58,"Addresses":["孙桥5号, 珠林市, Costa Rica"],"Created":"2024-02-11T08:16:49.1807504+08:00"}

可以看出默认是en 英文,通过设置locale可以实现国际化的输出。

生成相同数据集

// 如果您希望生成可重复的数据集,请设置随机数种子。
Randomizer.Seed = new Random(8675309);

这段代码用于设置随机数生成器的种子,以便生成可重复的数据集。通过指定一个固定的种子值,可以确保每次运行生成的随机数据都是相同的,从而实现数据集的重复性。

这个比较有意思,我们来做个 demo,要求随机生成五个对象 要求下一次运行生成的还是同一批对象。
BogusSeed 就很容易实现。

   [Fact]
   public void Bogus_Compare_SeedTest()
   {
       // Arrange
       var faker = new Faker<Staff>()
           .RuleFor(u => u.Name, f => f.Person.FullName)
           .RuleFor(u => u.Email, f => f.Person.Email)
           .RuleFor(u => u.Age, f => f.Random.Number(18, 60))
           .RuleFor(u => u.Addresses, f => f.MakeLazy(f.Random.Number(1, 3), () => f.Address.FullAddress()).ToList())
           .RuleFor(u => u.Created, f => f.Date.PastOffset());

       // Act
       var staffs1 = Enumerable.Range(1, 5)
           .Select(_ => faker.UseSeed(_).Generate())
           .ToList();

       OutputStaffInformation(staffs1, "第一次");

       var staffs2 = Enumerable.Range(1, 5)
           .Select(_ => faker.UseSeed(_).Generate())
           .ToList();

       OutputStaffInformation(staffs2, "第二次");

       // Assert
       Assert.True(staffs1.All(staff1 => staffs2.Any(staff2 => staff1.Name == staff2.Name && staff1.Email == staff2.Email)));
   }

   private void OutputStaffInformation(List<Staff> staffs, string iteration)
   {
       foreach (Staff staff in staffs)
       {
           testOutputHelperAccessor.Output?.WriteLine($"{iteration}: name: {staff.Name}, email: {staff.Email}");
       }
   }
  • Arrange 部分初始化了一个 Faker<Staff> 实例,并定义了一系列规则来生成 Staff 对象。
  • Act 部分通过使用不同的种子值,生成了两组包含 5 个 Staff 对象的列表,并输出了每个 Staff 对象的姓名和邮箱信息。
  • Assert 部分使用断言验证了两组生成的 Staff 列表中是否存在具有相同姓名和邮箱的对象,即通过 All 和 Any 方法进行比较。

通过使用不同的种子值来生成多组数据,然后断言这些数据中是否存在相同的姓名和邮箱信息。

Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

Bogus Api 支持

Bogus之所以提供这么方便的假数据生成,得益于封装了开箱即用的获取各类数据的方法,如:

Address

  • ZipCode - 获取邮政编码。
  • City - 获取城市名称。
  • StreetAddress - 获取街道地址。
  • CityPrefix - 获取城市前缀。
  • CitySuffix - 获取城市后缀。
  • StreetName - 获取街道名称。
  • BuildingNumber - 获取建筑编号。
  • StreetSuffix - 获取街道后缀。
  • SecondaryAddress - 获取次要地址,如 '公寓 2' 或 '321 号套房'。
  • County - 获取县名。
  • Country - 获取国家。
  • FullAddress - 获取完整地址,包括街道、城市、国家。
  • CountryCode - 获取随机的 ISO 3166-1 国家代码。
  • State - 获取随机州名。
  • StateAbbr - 获取州名缩写。
  • Latitude - 获取纬度。
  • Longitude - 获取经度。
  • Direction - 生成基数或序数方向,例如:西北、南、西南、东。
  • CardinalDirection - 生成基数方向,例如:北、南、东、西。
  • OrdinalDirection - 生成序数方向,例如:西北、东南、西南、东北。

Commerce

  • Department - 获取随机商务部门。
  • Price - 获取随机产品价格。
  • Categories - 获取随机产品类别。
  • ProductName - 获取随机产品名称。
  • Color - 获取随机颜色。
  • Product - 获取随机产品。
  • ProductAdjective - 随机产品形容词。
  • ProductMaterial - 随机产品材料。
  • Ean8 - 获取随机的 EAN-8 条形码号码。
  • Ean13 - 获取随机的 EAN-13 条形码号码。

后面的可以查看官网 Api 官网地址在文末...

Bogus 库提供了丰富的 API 支持,涵盖了各种数据类型和用例,包括地址、商务、日期、金融、图片、互联网、Lorem 文本、姓名、电话等方面的虚假数据生成方法。

Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

EFCore 利用 Bogus 生成种子数据

在我们的Sample.Repository中设置种子数据

  • 使用 Bogus 库生成虚假数据,填充到 Staffs 列表

public class FakeData
{
    public static List<Staff> Staffs = [];

    public static void Init(int count)
    {
        var id = 1;
        var faker = new Faker<Staff>()
            .RuleFor(_ => _.Id, f => id++)
       .RuleFor(u => u.Name, f => f.Person.FullName)
       .RuleFor(u => u.Email, f => f.Person.Email)
       .RuleFor(u => u.Age, f => f.Random.Number(18, 60))
       .RuleFor(u => u.Addresses, f => f.MakeLazy(f.Random.Number(1, 3), () => f.Address.FullAddress()).ToList())
       .RuleFor(u => u.Created, f => f.Date.PastOffset());
        var staffs = faker.Generate(count);
        FakeData.Staffs.AddRange(staffs);
    }
}
  • Program 写入 1000 条种子数据

using (var context = app.Services.CreateScope().ServiceProvider.GetRequiredService<SampleDbContext>())
{
    context.Database.EnsureCreated();
    FakeData.Init(1000);
    await context.Staffs.AddRangeAsync(FakeData.Staffs);
    await context.SaveChangesAsync();
}

我这地方用的是Microsoft.EntityFrameworkCore.InMemory内存数据库,正常如果使用像Sqlserver,MySQLCodeFirst模式可以在 DbContext 的OnModelCreating配置种子数据。

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        //FakeData.Init(1000);
        //builder.Entity<Staff>().HasData(FakeData.Staffs);
    }

来测试一下

通过我们Sample.Api提供的GetAll的方法测试一下种子数据

Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

正好一千条测试数据,大功告成。

最后

在软件开发中,使用 Bogus 可以极大地简化测试数据的创建过程,同时结合 EFCore 的种子数据功能,可以快速生成并初始化数据库中的虚假数据。这种方法不仅提高了开发效率,还能确保测试数据的质量和一致性。通过本文的示例和说明,希望您能更加熟悉如何利用 BogusEFCore 来生成模拟数据和种子数据,从而为软件开发过程提供更好的支持和帮助,我们有大量数据的测试需求时,也不用再为创造数据而烦恼。

😄欢迎关注笔者公众号一起学习交流,获取更多有用的知识~
Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】

  • Bogus Github

  • 本文完整源代码文章来源地址https://www.toymoban.com/news/detail-854307.html

到了这里,关于Bogus 实战:使用 Bogus 和 EFCore 生成模拟数据和种子数据【完整教程】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python使用Faker库进行生成模拟mock数据(基本使用+五个小案例)

    当我们要进行一些数据可视化的制作时,数据是必备的,但当我们手头没有真实数据又没有时间和精力去kaggle或其他网站收集数据时,且数据真实性不是特别需要时,我们可以使用faker库来进行数据的mock操作。 这就不需要爬虫去爬取真实数据,也不需要使用别人制作的API接口

    2024年02月11日
    浏览(42)
  • Unity如何生成随机数(设置种子)

    我们可以使用Random类来生成一些随机数 Random类是用于生成随机数的类之一。它可以用于生成不同类型的随机数,如整数、浮点数和向量。 我们可以使用Random.Range来生成指定范围内的随机整数或浮点数。下面举两个例子: 运行结果如下所示: 使用Random.insideUnitCircle来获取一个

    2024年02月04日
    浏览(41)
  • Mybatis generator实战:自动生成POJO类完整解决方案

    在用Mybatis generator 生成可以用来访问(多个)表的基础对象,遇到一个问题,就是columnRenamingRule可以替换所有表元素里字段前缀 但是如果想去掉所有表的前缀,比如有多个表: 期望得到的POJO结果是: 参照: https://github.com/mybatis/generator/issues/275 https://github.com/mybatis/generator/

    2024年02月04日
    浏览(39)
  • 【五一创作】【Midjourney】Midjourney 连续性人物创作 ② ( 获取大图和 Seed 随机种子 | 通过 seed 随机种子生成类似图像 )

    注意 : 一定是使用 U 按钮 , 在生成的大图的基础上 , 添加 信封 表情 , 才能获取该大图的 Seed 种子编码 ; 在上一篇博客生成图像的基础上 , 点击 U3 获取第三张图的大图 ; 获取到生成的大图之后 , 右键点击图片 , 在弹出的菜单中选择 \\\" 添加反应 / 显示更多 \\\" , 在弹出的对话框中

    2024年02月10日
    浏览(46)
  • 伪随机生成器(rand函数),随机数种子(srand函数)详细解读与分析:

    a.生成随机数; b.生成0~100以内的随机数 c.随机数的连续输出及其连续输出情况讲解与分析 首先我们来看一下rand函数(伪随机数生成器):   rand函数,即伪随机数生成器,该函数返回类型为整型,没有参数,即产生一个在(0-rand_max(十六进制的ox7ffff转化为整数即32767)的一个

    2024年02月11日
    浏览(52)
  • 使用Python生成二维码的完整指南

    无边落木萧萧下,不如跟着可莉一起游~ 可莉将这篇博客收录在了:《Python》 可莉推荐的优质博主首页:Kevin ’ s blog 本文将介绍如何使用Python中的 qrcode 库来生成二维码。通过简单的代码示例和详细解释,读者将学习如何在Python中轻松生成自定义的二维码。 目录 1、安装qr

    2024年02月19日
    浏览(62)
  • 数据生成 | MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成

    生成效果 基本描述 1.MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成; 2.马尔科夫链蒙特卡洛方法(Markov Chain Monte Carlo),简称MCMC,MCMC算法的核心思想是我们已知一个概率密度函数,需要从这个概率分布中采样,来分析这个分布的一些统计特性。 模型描述 马尔科夫蒙特卡洛模

    2024年02月11日
    浏览(44)
  • 数据仓库入门介绍框架(附带完整项目实战)

    一、诞生背景 企业数据分析需要:各个部门自己建立独立的数据抽取系统,导致数据不一致 概述 数据仓库是一个面向主题的、集成、非易失的且随时间变化的数据集合 主要用于组织积累的历史数据,并使用分析方法(OLAP、数据分析)进行分析整理辅助决策,为管理者、企

    2024年01月18日
    浏览(39)
  • python 数据分析可视化实战 超全 附完整代码数据

    代码+数据:https://download.csdn.net/download/qq_38735017/87379914 1.1.1 异常值检测 ①将支付时间转为标准时间的过程中发生错误,经排查错误数据为‘2017/2/29’,后将其修改为‘2017/2/27’。 ②经检测发现部分订单应付金额与实付金额都为0,抹去这部分异常数据。 ③在检测过程中发现部

    2024年02月02日
    浏览(40)
  • 大数据构建知识图谱:从技术到实战的完整指南

    本文深入探讨了知识图谱的构建全流程,涵盖了基础理论、数据获取与预处理、知识表示方法、知识图谱构建技术等关键环节。 知识图谱,作为人工智能和语义网技术的重要组成部分,其核心在于将现实世界的对象和概念以及它们之间的多种关系以图形的方式组织起来。它不

    2024年02月22日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包