• Java开源工具库使用之虚假数据生成库datafaker


    前言

    在开发和测试过程中,经常碰见需要构造虚假数据进行测试的情况。这是很常见的场景,很多编程语言都有库提供虚假数据构造:

    开源库 datafaker 是 Java 相关虚假数据构造库,它是 java-faker 的替代产品,基于 Java 8 构建,具有最新的库和几个新添加的 Fake Generators。

    官方地址: https://www.datafaker.net/

    github 地址: https://github.com/datafaker-net/datafaker

    pom 依赖:

    <dependency>
        <groupId>net.datafakergroupId>
        <artifactId>datafakerartifactId>
        <version>1.6.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    一、简单使用

    datafaker 支持多种语言,默认英文,中文相关需要设置 Locale, 如下所示。

    Faker faker = new Faker(Locale.CHINA);
    
    • 1

    1.1 姓名

     Name name = faker.name();
     logger.info("{}", name.name()); 
    
    • 1
    • 2

    1.2 手机号码

    PhoneNumber phoneNumber = faker.phoneNumber();
    logger.info("{}", phoneNumber.cellPhone()); 
    
    • 1
    • 2

    1.3 地址

    Address address = faker.address();
    logger.info("{}, {}, {}", address.state(), address.city(), address.streetAddress()); 
    
    • 1
    • 2

    1.4 时间

    DateAndTime date = faker.date();
    logger.info("{}, {}", date.birthday("yyyy年MM月dd日HH时mm分ss秒"), date.between(Timestamp.valueOf("2000-01-01 00:00:00"), Timestamp.valueOf("2099-12-31 23:59:59"))); // 1989年11月02日09时15分42秒, 2048-10-17 21:30:01.383
    
    • 1
    • 2

    1.5 大学

    University university = faker.university();
    logger.info("{}", university.name()); 
    
    • 1
    • 2

    1.6 其它

    datafaker 提供了非常多的生成器,具体可以见:https://www.datafaker.net/documentation/providers/,但是除了上述部分,都是英文相关的,例如:电影,天气,书籍等等。其实也可以通过配置 yml 文件将电影、天气、书籍等中文数据参与构造假数据,通过看源码发现这些假数据都是通过配置文件配置,然后随机选择的,只不过生成器关于中文的比较少。具体操作可以查看下面 高级用法 自定义

    二、高级用法

    2.1 集合

    // 随机生成3-5个姓名
    List<String> names =
            faker.collection(() -> faker.name().name())
                 .len(3, 5)
                 .generate();
    logger.info("{}", names); // [龚思源, 彭弘文, 邱睿渊]
    
    // 随机生成10个身份证号码,其中 30% 为null
    List<String> ids = faker.collection(() -> faker.idNumber().validZhCNSsn()).len(10).nullRate(0.3).generate();
    logger.info("{}", ids);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 自定义数据

    1. 硬编码数据

      public static class Movie extends AbstractProvider {
          private static final String[] MOVIE_NAMES = new String[]{ "肖申克的救赎", "霸王别姬", "阿甘正传", "泰坦尼克号",
                  "这个杀手不太冷", "美丽人生", "千与千寻", "辛德勒的名单", "盗梦空间", "忠犬八公的故事" };
      
          public Movie(Faker faker) {
              super(faker);
          }
      
          public String movie() {
              return MOVIE_NAMES[faker.random().nextInt(MOVIE_NAMES.length)];
          }
      }
      
      public static class MyCustomFaker extends Faker {
          
          public MyCustomFaker(Locale locale) {
                  super(locale);
          }
          
          public Movie myMovie() {
              return getProvider(Movie.class, () -> new Movie(this));
          }
      }
      
      @Test
      public void testFaker() {
          MyCustomFaker customFaker = new MyCustomFaker(Locale.CHINA);
          Movie movie = customFaker.myMovie();
          logger.info("{}", movie.movie());
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
    2. 配置文件配置数据

      # coding: utf-8
      zh-CN:
        faker:
          books:
            names: ['代码整洁之道', 'Java 编程思想', 'Java 编程从入门到入土']
            authors: ['马丁(Robert C. Martin)', 'Bruce Eckel', 'aabond']
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      public static class MyCustomFaker extends Faker {
      
          public MyCustomFaker(Locale locale) {
              super(locale);
          }
          public Movie myMovie() {
              return getProvider(Movie.class, () -> new Movie(this));
          }
      
          public BookFromFile bookFromFile() {
              return getProvider(BookFromFile.class, () -> new BookFromFile(this));
          }
      }
      
      public static class BookFromFile extends AbstractProvider {
          private static final String KEY = "books";
      
          public BookFromFile(Faker faker) {
              super(faker);
              faker.addPath(Locale.CHINA, Paths.get("src/test/java/books.yml"));
          }
      
          public String names() {
              return faker.resolve(KEY + ".names");
          }
          public String authors() {
              return faker.resolve(KEY + ".authors");
          }
      }
      
      @Test
      public void testFaker() {
          MyCustomFaker customFaker = new MyCustomFaker(Locale.CHINA);
         
          BookFromFile bookFromFile = customFaker.bookFromFile();
          logger.info("{}, {}", bookFromFile.names(), bookFromFile.authors());
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37

    2.3 表达式

    String e1 = faker.expression("#{letterify 'test????test'}");        // 将?替换为随机字母
    String e2 = faker.expression("#{numerify '#test#'}");               // 将#替换为随机数字
    String e3 = faker.expression("#{bothify '?#?#?#?#'}");              // 上述组合
    String e4 = faker.expression("#{Name.last_name}#{Name.first_name}");// 能够调用其他Provider类
    String e5 = faker.expression("#{templatify 'test','t','q','@'}");   // 能够将字符替换
    
    
    logger.info("{}, {}, {}, {}, {}", e1, e2, e3, e4, e5);
    // testzvkgtest, 6test3, r3t4f3x5, 宋梓晨, qes@
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.4 json 数据

    String json = Format.toJson(
                    faker.collection(faker::name)
                         .len(2)
                         .build())
            .set("firstName", Name::firstName)
            .set("lastName", Name::lastName)
            .build()
            .generate();
    
    logger.info("{}", json); // [{"firstName": "绍齐", "lastName": "龙"},{"firstName": "聪健", "lastName": "韦"}]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    参考

    1. https://www.datafaker.net/documentation/getting-started/
  • 相关阅读:
    GPU--学习笔记
    Java“牵手”义乌购商品详情数据,义乌购商品详情接口,义乌购API接口申请指南
    明阳天下团建游戏------围城
    LeetCode 452. 用最少数量的箭引爆气球
    JumpServer开源堡垒机与爱可生云树数据库完成兼容性认证
    2023/11/21JAVAweb学习
    项目总结——深入浅出socket网络编程
    猿创征文 第二季| #「笔耕不辍」--生命不息,写作不止#
    车载导航进阶「不输」手机,哪些供应商在领跑导航引擎赛道
    Vue3.x 中eventBus -- mitt用法
  • 原文地址:https://blog.csdn.net/qq_23091073/article/details/126814128