{"id":19993285,"url":"https://github.com/developframework/mock","last_synced_at":"2026-01-11T17:47:53.073Z","repository":{"id":57719712,"uuid":"131936797","full_name":"developframework/mock","owner":"developframework","description":"随机数据框架","archived":false,"fork":false,"pushed_at":"2020-01-16T08:55:57.000Z","size":141,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-13T04:56:15.124Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/developframework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-03T03:26:12.000Z","updated_at":"2023-04-27T15:12:06.000Z","dependencies_parsed_at":"2022-09-13T13:01:55.208Z","dependency_job_id":null,"html_url":"https://github.com/developframework/mock","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developframework%2Fmock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developframework%2Fmock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developframework%2Fmock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developframework%2Fmock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developframework","download_url":"https://codeload.github.com/developframework/mock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252334284,"owners_count":21731371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T04:52:34.013Z","updated_at":"2026-01-11T17:47:53.034Z","avatar_url":"https://github.com/developframework.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# Mock\n\n一个伪造数据的框架，用来方便随机生成一些数据。\n\n## 基本用法\n\n引用依赖Maven：\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.developframework\u003c/groupId\u003e\n    \u003cartifactId\u003emock-text\u003c/artifactId\u003e\n    \u003cversion\u003e${version.mock}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n提供一个模板字符串（template），可以内嵌占位符`${...}`，占位符将会被随机值替换。\n\n生成一个：\n\n```java\nMockClient mockClient = new MockClient();\nString result = mockClient.mock(\"random text: ${ string }\");\nSystem.out.println(result);\n```\n\n```\nrandom text: pXFMyu\n```\n\n批量生成：\n\n```java\nList\u003cString\u003e list = mockClient.mock(\"random text: ${ string }\", 5);\nlist.forEach(System.out::println);\n```\n\n```\nrandom text: PDsUUg\nrandom text: zcVIFN\nrandom text: YFORrL\nrandom text: rnYSpZ\nrandom text: fCmrto\n```\n\n从输入流引入模板：\n\n```java\nString result = mockClient.mock(inputStream, charset);\n```\n\n从输入流引入模板批量生成\n\n```java\nList\u003cString\u003e list = mockClient.mock(inputStream, charset, quantity);\n```\n\n### 占位符\n\n占位符的格式：\n\n```\n${ \u003ctype\u003e | [ param1=value1, param2='value2' ] }\n```\n\n+ type是占位符的类型\n+ param=value是可选的参数，对随机值做约束，boolean型的`param=true`可以省略直接写`param`\n+ Mock可以自动识别所填参数是什么基本类型，在有歧义的情况下，最好还是用单引号申明字符串值，比如`'1234'`\n\n比如：\n\n```\n${ string | length=10, uppercase }\n```\n\n将会生成一个10位长度的全大写的随机字母字符串\n\n目前所有内置的占位符\n\n#### **string**\n\n随机字符串\n\n```\n${ string | length=10, letters, numbers, uppercase, lowercase }\n```\n\n| 可用参数  | 说明       | 默认值 | 随机示例                 | 示例结果   |\n| --------- | ---------- | ------ | ------------------------ | ---------- |\n| length    | 字符串长度 | 6      | ${ string \\| length=10 } | UvmNUqOACS |\n| letters   | 使用字母   | true   | ${ string \\| letters }   | EETnby     |\n| numbers   | 使用数字   | false  | ${ string \\| numbers }   | 236914     |\n| uppercase | 使用大写   | false  | ${ string \\| uppercase } | LHKRDU     |\n| lowercase | 使用小写   | false  | ${ string \\| lowercase } | mgpval     |\n\n+ `uppercase`和`lowercase`都写和都不写时，大小写混合。\n\n#### **number**\n\n随机数值\n\n```\n${ number | min=0, max=100, decimals }\n```\n\n| 可用参数 | 说明         | 默认值           | 随机示例                           | 示例结果          |\n| -------- | ------------ | ---------------- | ---------------------------------- | ----------------- |\n| min      | 最小值       | 0                | ${ number \\| min=0 }               | 4                 |\n| max      | 最大值       | Double.MAX_VALUE | ${ number \\| min=100 }             | 20                |\n| decimals | 采用小数     | false            | ${ number \\| decimals }            | 82.30656374435402 |\n| digit    | 有效位数     | null             | ${ number \\| decimals, digit = 2 } | 91.02             |\n| fillZero | 整数前面补零 | null             | ${ number \\| fillZero = 4 }        | 0096              |\n\n#### **boolean**\n\n随机布尔值\n\n```\n${ boolean }\n```\n\n#### **enum**\n\n随机枚举值\n\n```\n${ enum | AAA, BBB, CCC }\n```\n\n#### **date**\n\n随机日期\n\n```\n${ date | range=1y, pattern=yyyy-MM-dd, future }\n```\n\n| 可用参数 | 说明                                             | 默认值     | 随机示例                        | 示例结果   |\n| -------- | ------------------------------------------------ | ---------- | ------------------------------- | ---------- |\n| range    | 日期范围，相对于系统日期浮动，格式：1y1M1d1h1m1s | 1y         | ${ date \\| range=1y }           | 2018-03-20 |\n| pattern  | 日期格式化                                       | yyyy-MM-dd | ${ date \\| pattern=yyyy/MM/dd } | 2018/03/20 |\n| future   | 随机一个未来的日期，默认是已过的日期             | false      | ${ date \\| future }             | 2018-05-16 |\n\n#### **time**\n\n随机时间\n\n```\n${ time | range=1h, pattern=HH:mm:ss, future }\n```\n\n可用参数和**date**类型一致，区别是`pattern`参数默认值是HH:mm:ss， `range`的默认值是1h\n\n#### **datetime**\n\n随机日期和时间\n\n```\n${ datetime | range=1y, pattern=yyyy-MM-dd HH:mm:ss, future }\n```\n\n可用参数和**date**类型一致，区别是`pattern`参数默认值是yyyy-MM-dd HH:mm:ss\n\n#### **mobile**\n\n随机手机号码\n\n```\n${ mobile }\n```\n\n#### **personName**\n\n随机人名\n\n```\n${ personName | length=3 }\n```\n\n| 可用参数 | 说明     | 默认值 | 随机示例                    | 示例结果 |\n| -------- | -------- | ------ | --------------------------- | -------- |\n| length   | 名字字数 | 3      | ${ personName \\| length=3 } | 王悦议   |\n| onlyName | 只生成名 | false  | ${ personName \\| onlyName } | 悦议     |\n\n#### **address**\n\n随机地址\n\n```\n${ address | level=3 }\n```\n\n| 可用参数 | 说明                               | 默认值 | 随机示例                                         | 示例结果           |\n| -------- | ---------------------------------- | ------ | ------------------------------------------------ | ------------------ |\n| level    | 地址层数                           | 3      | ${ address \\| level=3 }                          | 浙江省杭州市富阳区 |\n| province | 限定省份范围                       | null   | ${ address \\| province = 浙江省 }                | 浙江省嘉兴市南湖区 |\n| city     | 限定城市范围（要先限定省份才有效） | null   | ${ address \\| province = 浙江省, city = 嘉兴市 } | 浙江省嘉兴市南湖区 |\n\n数据提供器参见独立项目[chinese-administrative-region](https://github.com/developframework/chinese-administrative-region)\n\n#### **identityCard**\n\n随机身份证号\n\n```\n${ identityCard | birthday-ref=random, range=30y }\n```\n\n| 可用参数     | 说明     | 默认值 | 随机示例                               | 示例结果           |\n| ------------ | -------- | ------ | -------------------------------------- | ------------------ |\n| birthday-ref | 生日依赖 | random | ${ personName \\| birthday-ref=random } | 152028201408159388 |\n| address-ref  | 地区依赖 | random | ${ personName \\| address-ref=random }  | 152028201408159388 |\n| sex-ref      | 性别依赖 | random | ${ personName \\| sex-ref=FEMALE }      | 152028201408159388 |\n| range        | 生日范围 | 30y    | ${ identityCard \\| range=30y }         | 914951199607233405 |\n\n```java\nString sex = mockClient.mock(\"sex: ${ enum | id = anySex, MALE, FEMALE }\");\nString address = mockClient.mock(\"address: ${ address | id = anyAddress, province = 浙江省, city = 嘉兴市 }\");\nString birthday = mockClient.mock(\"birthday: ${ date | id = anyBirthday, range = 30y }\");\nString identityCard = mockClient.mock(\"identityCard: ${ identityCard | address-ref = anyAddress, birthday-ref = anyBirthday, sex-ref = anySex }\");\n```\n\n```\nsex: FEMALE\naddress: 浙江省嘉兴市嘉善县\nbirthday: 1989-08-09\nidentityCard: 330421198908090074\n```\n\n+ `birthday-ref`可以引用之前出现过的生日日期，生成更加严谨的身份证号\n+ `address-ref`可以引用之前出现过的地址，生成更加严谨的身份证号\n\n#### **ip**\n\n随机IP号\n\n```\n${ ip | prefix = '192.168' }\n```\n\n| 可用参数 | 说明       | 默认值 | 随机示例                        | 示例结果     |\n| -------- | ---------- | ------ | ------------------------------- | ------------ |\n| prefix   | IP前缀网段 | null   | ${ ip \\| prefix = '192.168.1' } | 192.168.1.55 |\n\n这里的`prefix`最好使用单引号括起来，避免数字字符串引起类型歧义。\n\n#### **quote**\n\n这个类型本身不生成随机值，引用之前已生成的随机值\n\n```java\nString firstText = mockClient.mock(\"first： ${ string | id = first }\");\nString secondText = mockClient.mock(\"quote： ${ quote | ref = first }\");\nSystem.out.println(firstText);\nSystem.out.println(secondText);\n```\n给之前的占位符设置一个`id` 在后面使用**quote**类型引用之前的值\n\n```\nfirst： GtHQra\nquote： GtHQra\n```\n\n### 自定义占位符\n\n继承随机生成器接口`com.github.developframework.mock.random.RandomGenerator`\n\n```java\n// \u003cT\u003e 是随机值的类型\npublic interface RandomGenerator\u003cT\u003e {\n\n    // 描述如何生成随机值\n    T randomValue(RandomGeneratorRegistry randomGeneratorRegistry, MockPlaceholder mockPlaceholder, MockCache mockCache);\n\n    // 识别占位符的名称\n    String name();\n    \n    // 描述随机值如何转换到字符串\n    String forString(MockPlaceholder mockPlaceholder, T value);\n}\n```\n\n```java\npublic class MyRandomGenerator implements RandomGenerator\u003cString\u003e{\n    @Override\n    public String randomValue(MockPlaceholder mockPlaceholder, MockCache mockCache) {\n        // 获得参数\n        String param = mockPlaceholder.getParameterOrDefault(\"param\", String.class, \"default value\");\n        \n        // 返回随机值\n        return null;\n    }\n\n    @Override\n    public String name() {\n        return \"myPlaceholder\";\n    }\n    \n    @Override\n    String forString(MockPlaceholder mockPlaceholder, T value) {\n        return value;\n    }\n}\n```\n\n给MockClient注册自定义随机生成器\n\n```java\nRandomGenerator[] customRandomGenerators = new RandomGenerator[] {\n    new MyRandomGenerator()\n};\nmockClient.getRandomGeneratorRegistry().customRandomGenerators(customRandomGenerators);\n```\n\n## Mock-db\n\n给数据库表随机填充数据框架\n\n引用依赖Maven：\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.developframework\u003c/groupId\u003e\n    \u003cartifactId\u003emock-db\u003c/artifactId\u003e\n    \u003cversion\u003e${version.mock}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n提交一条随机数据\n\n```java\nDBMockClient client = new DBMockClient(driver, url, user, password);\ntry {\n    int count = client.byMysql()\n            .database(\"test\")\n            .table(\"person\")\n            .field(\"name\", \"${ personName }\")\n            .field(\"birthday\", \"${ date | range=20y }\")\n            .field(\"mobile\", \"${ mobile }\")\n            .field(\"address\", \"${ address }\")\n            .submit();\n    System.out.println(count);\n} catch (SQLException e) {\n    e.printStackTrace();\n}\n```\n\n批量提交随机数据：\n\n```java\nint count = client.byMysql()\n    // 忽略表配置\n    .submit(100);\n```\n\n![](doc-images/mock-db-image1.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopframework%2Fmock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevelopframework%2Fmock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevelopframework%2Fmock/lists"}