{"id":15521864,"url":"https://github.com/gungnirlaevatain/mock","last_synced_at":"2025-10-11T20:17:51.615Z","repository":{"id":37144783,"uuid":"204005918","full_name":"GungnirLaevatain/mock","owner":"GungnirLaevatain","description":"Based on the external mapping file, mock target method.基于外部映射文件， 模拟目标方法，返回模拟结果","archived":false,"fork":false,"pushed_at":"2022-12-14T20:41:50.000Z","size":75,"stargazers_count":0,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-11T05:55:23.639Z","etag":null,"topics":["java","mock","mock-data","mocking","mocking-framework","test","testing","testing-tools","tool"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GungnirLaevatain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-23T13:40:34.000Z","updated_at":"2020-01-20T01:36:36.000Z","dependencies_parsed_at":"2023-01-29T01:00:53.644Z","dependency_job_id":null,"html_url":"https://github.com/GungnirLaevatain/mock","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/GungnirLaevatain/mock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GungnirLaevatain%2Fmock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GungnirLaevatain%2Fmock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GungnirLaevatain%2Fmock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GungnirLaevatain%2Fmock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GungnirLaevatain","download_url":"https://codeload.github.com/GungnirLaevatain/mock/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GungnirLaevatain%2Fmock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274564545,"owners_count":25308607,"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","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","mock","mock-data","mocking","mocking-framework","test","testing","testing-tools","tool"],"created_at":"2024-10-02T10:38:14.311Z","updated_at":"2025-10-11T20:17:46.562Z","avatar_url":"https://github.com/GungnirLaevatain.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MOCK\n[**中文说明**](https://github.com/GungnirLaevatain/mock/blob/master/README_cn.md)  \nDevelopers often mock external interfaces for testing, so there's a lot of test code in the business code.This reduces readability and maintainability.  \nTo solve this problem, we plan to move the test code to the configuration file, and then use **javaassist** or **spring aop** to process the target object or class.  \nBased on this plan, we have developed this tool.\n## Getting Started  \n### Adding Maven Dependencies  \n```xml\n\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.gungnirlaevatain\u003c/groupId\u003e\n  \u003cartifactId\u003emock\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n\n```\n### Create a new configuration file  \n1. create a new folder named **mock** in classpath\n2. create a new text file in **YAML** format in **mock**,such as class.yml \n### Write configuration information\nWrite configuration information to the file  \n### Run\nRun your project  \n## Configuration\n### Configuration example\n```\nentities:\n  # specify the mock mode to use\n  - type: BEAN_REPLACE\n    # specify target class\n    className: com.github.gungnirlaevatain.mock.sample.replace.ReplaceTestServiceImpl\n    methods:\n      # specify target method\n      - method: testReturnObjectByDefault\n        # default value\n        defaultResult: '{\"a\":\"AAA\",\"b\":3,\"c\":\"2019-07-23 00:32:00\",\"d\":{\"a\":\"BBB\"}}'\n      - method: testReturnObjectByParam\n        # specify the return value under different conditions\n        results:\n            # Get the input parameter based on the syntax of jsonpath. \n            # The root node is an array of input parameters\n          - path: $.0\n            # Expected value\n            expected: 1\n            # When the input parameter value is equal to the expected value, return the defined result\n            result: '{\"a\":\"AAA\"}'\n          - path: $.1\n            expected: 'B'\n            result: '{\"a\":\"BBB\"}'\n          - path: $.2.a\n            expected: 'CCC'\n            result: '{\"a\":\"CCC\"}'\n      - method: testVoid\n        defaultResult: '{\"a\":\"AAA\",\"b\":3,\"c\":\"2019-07-23 00:32:00\",\"d\":{\"a\":\"BBB\"}}'\n      - method: testReturnString\n        defaultResult: 'true'\n      - method: testReturnInt\n        defaultResult: '1'\n      - method: testReturnInt\n        # For overloaded methods, need to specify the type of the input parameter\n        paramClass:\n          - java.lang.String\n        defaultResult: 2\n      - method: testReturnInt\n        paramClass:\n          - java.lang.String\n          - com.github.gungnirlaevatain.mock.sample.TestResult\n        defaultResult: \"3\"\n\n```\n### Configuration information  \n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003ekey\u003c/th\u003e\u003cth\u003etype\u003c/th\u003e\u003cth\u003edefault value\u003c/th\u003e\u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e  \n   \u003c/thead\u003e\n   \u003ctbody\u003e\n    \u003ctr\u003e \u003ctd\u003eentities\u003c/td\u003e\u003ctd\u003eList\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003eroot key\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;├─type\u003c/td\u003e \u003ctd\u003eString\u003c/td\u003e\u003ctd\u003eBEAN_PROXY\u003c/td\u003e \u003ctd\u003emock mode\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;├─className\u003c/td\u003e \u003ctd\u003eString\u003c/td\u003e\u003ctd\u003enull\u003c/td\u003e \u003ctd\u003etarget class name\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;├─methods\u003c/td\u003e\u003ctd\u003eList\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003etarget methods\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─method\u003c/td\u003e\u003ctd\u003eString\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003etarget method name\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─defaultResult\u003c/td\u003e\u003ctd\u003eString\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003edefault return value. If it is an object, it is a string in JSON format\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─paramClass\u003c/td\u003e\u003ctd\u003eList\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003ethe list of the input parameter class name\u003c/td\u003e \u003c/tr\u003e\n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─results\u003c/td\u003e\u003ctd\u003eList\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003erules for returning results\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─path\u003c/td\u003e\u003ctd\u003eString\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003eget the input parameter based on the syntax of jsonpath,the root node is an array of input parameters\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─expected\u003c/td\u003e\u003ctd\u003eString\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003eexpected value\u003c/td\u003e \u003c/tr\u003e \n    \u003ctr\u003e \u003ctd\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;├─result\u003c/td\u003e\u003ctd\u003eString\u003c/td\u003e \u003ctd\u003enull\u003c/td\u003e \u003ctd\u003ewhen the input parameter value is equal to the expected value, return the defined result\u003c/td\u003e \u003c/tr\u003e \n   \u003c/tbody\u003e\n\u003c/table\u003e  \n\n### Mock Mode   \n#### 1.BEAN_PROXY  \nBased on **BeanPostProcessor**, proxy target bean \n#### 2.BEAN_REPLACE \nBased on **InstantiationAwareBeanPostProcessor**, replace the target bean with a proxy instance when the target bean cannot be generated\n#### 3.CLASS  \nBased on **Javaassist**, modify target class\n## Sample Code\n### Example   \n- Write the target class\n```\n@Service\n@Slf4j\npublic class ProxyTestServiceImpl implements ProxyTestService {\n    /**\n     * Test return object by default.\n     *\n     * @return the proxy test result\n     * @author GungnirLaevatain\n     */\n    @Override\n    public TestResult testReturnObjectByDefault() {\n        return null;\n    }\n}\n@Data\npublic class TestResult {\n\n    private String a;\n    private Integer b;\n    private Date c;\n    private TestResult d;\n}\n```\n- Define configuration\n```\nentities:\n  - type: BEAN_PROXY\n    className: com.github.gungnirlaevatain.mock.sample.proxy.ProxyTestService\n    methods:\n      - method: testReturnObjectByDefault\n        defaultResult: '{\"a\":\"AAA\",\"b\":3,\"c\":\"2019-07-23 00:32:00\",\"d\":{\"a\":\"BBB\"}}'\n```\n- Write test class\n```\n@RunWith(SpringRunner.class)\n@SpringBootTest(classes = MockSampleApplication.class)\npublic class BeanProxyTest {\n\n    @Autowired\n    private ProxyTestService proxyTestService;\n\n    /**\n     * Method: testReturnObjectByDefault()\n     */\n    @Test\n    public void testTestReturnObjectByDefault() throws Exception {\n        TestResult testResult = proxyTestService.testReturnObjectByDefault();\n        Assert.assertEquals(\"AAA\", testResult.getA());\n        Assert.assertNotNull(testResult.getC());\n        Assert.assertNotNull(testResult.getD());\n        Assert.assertEquals(0, 3 - testResult.getB());\n        Assert.assertEquals(\"BBB\", testResult.getD().getA());\n        System.out.println(testResult);\n    }\n}\n```\n- Output\n```\nTestResult(a=AAA, b=3, c=Tue Jul 23 00:32:00 CST 2019, d=TestResult(a=BBB, b=null, c=null, d=null))\n```\n### Details\n[See **mock-sample** module](https://github.com/GungnirLaevatain/mock/tree/master/mock-sample)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgungnirlaevatain%2Fmock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgungnirlaevatain%2Fmock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgungnirlaevatain%2Fmock/lists"}