You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2022/07/02 15:27:50 UTC

[incubator-shenyu] branch master updated: [ISSUE #3464] add new feature for mock plugin (#3599)

This is an automated email from the ASF dual-hosted git repository.

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 731df84b7 [ISSUE #3464]  add new feature for mock plugin (#3599)
731df84b7 is described below

commit 731df84b75f219b6d3e3265bff3c5fadc747d4ea
Author: LiuTianyou <64...@qq.com>
AuthorDate: Sat Jul 2 23:27:42 2022 +0800

    [ISSUE #3464]  add new feature for mock plugin (#3599)
    
    * Support generating random data by configuring ${}
    
    * Redesigned random data generator
    Remove part of data generator implementation
    
    * [type:feat]Redesigned random data generator
    
    * [type:feat]Redesigned random data generator
    
    * Refactor code based on review comments
---
 .../plugin/api/utils/WebFluxResultUtils.java       |  26 +----
 .../apache/shenyu/plugin/base/mock/Generator.java  |  87 +++++++++++++++++
 shenyu-plugin/shenyu-plugin-mock/pom.xml           |   5 +
 .../org/apache/shenyu/plugin/mock/MockPlugin.java  |  32 +++++--
 .../plugin/mock/generator/BoolGenerator.java       |  49 ++++++++++
 .../mock/generator/CurrentTimeGenerator.java       |  76 +++++++++++++++
 .../plugin/mock/generator/EmailGenerator.java      |  57 +++++++++++
 .../plugin/mock/generator/EnStringGenerator.java   |  63 ++++++++++++
 .../plugin/mock/generator/PhoneGenerator.java      |  54 +++++++++++
 .../mock/generator/RandomDoubleGenerator.java      |  71 ++++++++++++++
 .../plugin/mock/generator/RandomIntGenerator.java  |  62 ++++++++++++
 .../plugin/mock/generator/RangeDataGenerator.java  |  68 +++++++++++++
 .../plugin/mock/generator/ZhStringGenerator.java   |  66 +++++++++++++
 .../shenyu/plugin/mock/util/GeneratorFactory.java  | 106 +++++++++++++++++++++
 .../apache/shenyu/plugin/mock/util/RandomUtil.java |  50 ++++++++++
 .../org.apache.shenyu.plugin.base.mock.Generator   |  25 +++++
 .../plugin/mock/generator/BoolGeneratorTest.java   |  47 +++++++++
 .../mock/generator/CurrentTimeGeneratorTest.java   |  51 ++++++++++
 .../plugin/mock/generator/EmailGeneratorTest.java  |  46 +++++++++
 .../mock/generator/EnStringGeneratorTest.java      |  50 ++++++++++
 .../plugin/mock/generator/PhoneGeneratorTest.java  |  47 +++++++++
 .../mock/generator/RandomDoubleGeneratorTest.java  |  58 +++++++++++
 .../mock/generator/RandomIntGeneratorTest.java     |  48 ++++++++++
 .../mock/generator/RangeDataGeneratorTest.java     |  56 +++++++++++
 .../mock/generator/ZhStringGeneratorTest.java      |  51 ++++++++++
 25 files changed, 1320 insertions(+), 31 deletions(-)

diff --git a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/utils/WebFluxResultUtils.java b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/utils/WebFluxResultUtils.java
index f4eeaafbe..158cee585 100644
--- a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/utils/WebFluxResultUtils.java
+++ b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/utils/WebFluxResultUtils.java
@@ -23,7 +23,6 @@ import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
 import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
@@ -35,15 +34,15 @@ import java.util.Objects;
  * The type Shenyu result utils.
  */
 public final class WebFluxResultUtils {
-
+    
     /**
      * result utils log.
      */
     private static final Logger LOG = LoggerFactory.getLogger(WebFluxResultUtils.class);
-
+    
     private WebFluxResultUtils() {
     }
-
+    
     /**
      * Response result.
      *
@@ -63,7 +62,6 @@ public final class WebFluxResultUtils {
             mediaType = shenyuResult.contentType(exchange, resultData);
         }
         exchange.getResponse().getHeaders().setContentType(mediaType);
-
         final Object responseData = shenyuResult.result(exchange, resultData);
         assert null != responseData;
         final byte[] bytes = (responseData instanceof byte[])
@@ -72,21 +70,7 @@ public final class WebFluxResultUtils {
             .bufferFactory().wrap(bytes))
             .doOnNext(data -> exchange.getResponse().getHeaders().setContentLength(data.readableByteCount())));
     }
-
-    /**
-     * Response result and support specify the http status code .
-     *
-     * @param exchange   the exchange
-     * @param result     the result
-     * @param httpStatus the http status
-     * @return the result
-     */
-    public static Mono<Void> resultCustomStatusCode(final ServerWebExchange exchange, final Object result, final HttpStatus httpStatus) {
-        exchange.getResponse().setStatusCode(httpStatus);
-        return result(exchange, result);
-
-    }
-
+    
     /**
      * get no selector result.
      *
@@ -99,7 +83,7 @@ public final class WebFluxResultUtils {
         Object error = ShenyuResultWrap.error(exchange, ShenyuResultEnum.SELECTOR_NOT_FOUND.getCode(), pluginName + ":" + ShenyuResultEnum.SELECTOR_NOT_FOUND.getMsg(), null);
         return WebFluxResultUtils.result(exchange, error);
     }
-
+    
     /**
      * get no rule result.
      *
diff --git a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/mock/Generator.java b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/mock/Generator.java
new file mode 100644
index 000000000..1936373aa
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/mock/Generator.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.base.mock;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.shenyu.spi.SPI;
+
+/**
+ * Abstract generator.
+ */
+@SPI
+public interface Generator<T> {
+    
+    /**
+     * rule name.
+     *
+     * @return name
+     */
+    String getName();
+    
+    /**
+     * generate mock data.
+     *
+     * @return random data
+     */
+    T generate();
+    
+    /**
+     * get size of rule params.
+     *
+     * @return params size
+     */
+    int getParamSize();
+    
+    /**
+     * init generator.
+     *
+     * @param rule rule
+     */
+    default void parseRule(final String rule) {
+        List<String> params = new ArrayList<>();
+        String[] split = rule.split("(?<!\\\\)\\|");
+        if (split.length >= getParamSize() + 1) {
+            params.addAll(Arrays.stream(split)
+                .map(p -> p.replaceAll("\\\\\\|", "|"))
+                .skip(1)
+                .collect(Collectors.toList()));
+        }
+        initParam(params);
+    }
+    
+    /**
+     * param from rule.
+     *
+     * @param params rule params.
+     */
+    default void initParam(List<String> params) {
+    
+    }
+    
+    /**
+     * Determine whether the rule meets the format requirements.
+     *
+     * @param rule rule
+     * @return if match return true.
+     */
+    boolean match(String rule);
+    
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/pom.xml b/shenyu-plugin/shenyu-plugin-mock/pom.xml
index 0a389c5c0..2974afc8f 100644
--- a/shenyu-plugin/shenyu-plugin-mock/pom.xml
+++ b/shenyu-plugin/shenyu-plugin-mock/pom.xml
@@ -30,6 +30,11 @@
 
     <dependencies>
 
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-spi</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.shenyu</groupId>
             <artifactId>shenyu-common</artifactId>
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/MockPlugin.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/MockPlugin.java
index 5552bc659..13f8e9db9 100644
--- a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/MockPlugin.java
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/MockPlugin.java
@@ -17,16 +17,18 @@
 
 package org.apache.shenyu.plugin.mock;
 
+import java.nio.charset.StandardCharsets;
 import org.apache.shenyu.common.dto.RuleData;
 import org.apache.shenyu.common.dto.SelectorData;
 import org.apache.shenyu.common.dto.convert.rule.MockHandle;
 import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.plugin.api.ShenyuPluginChain;
-import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
 import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
 import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
 import org.apache.shenyu.plugin.mock.handler.MockPluginHandler;
+import org.apache.shenyu.plugin.mock.util.GeneratorFactory;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 
@@ -34,24 +36,34 @@ import reactor.core.publisher.Mono;
  * MockPlugin.
  */
 public class MockPlugin extends AbstractShenyuPlugin {
-
+    
     @Override
     protected Mono<Void> doExecute(final ServerWebExchange exchange,
-                                   final ShenyuPluginChain chain,
-                                   final SelectorData selector,
-                                   final RuleData rule) {
-        MockHandle mockHandle = MockPluginHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
-        return WebFluxResultUtils.resultCustomStatusCode(exchange, mockHandle.getResponseContent(), HttpStatus.valueOf(mockHandle.getHttpStatusCode()));
+        final ShenyuPluginChain chain,
+        final SelectorData selector,
+        final RuleData rule) {
+        MockHandle mockHandle = MockPluginHandler.CACHED_HANDLE.get()
+            .obtainHandle(CacheKeyUtils.INST.getKey(rule));
+        String replaceContent = GeneratorFactory.dealRule(mockHandle.getResponseContent());
+        
+        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
+        exchange.getResponse().setStatusCode(HttpStatus.valueOf(mockHandle.getHttpStatusCode()));
+        
+        final byte[] bytes = replaceContent.getBytes(StandardCharsets.UTF_8);
+        return exchange.getResponse().writeWith(Mono.just(exchange.getResponse()
+            .bufferFactory().wrap(bytes))
+            .doOnNext(data -> exchange.getResponse().getHeaders()
+                .setContentLength(data.readableByteCount())));
     }
-
+    
     @Override
     public int getOrder() {
         return PluginEnum.MOCK.getCode();
     }
-
+    
     @Override
     public String named() {
         return PluginEnum.MOCK.getName();
     }
-
+    
 }
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/BoolGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/BoolGenerator.java
new file mode 100644
index 000000000..14aeb8d6f
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/BoolGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.plugin.mock.util.RandomUtil;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Boolean Generator.
+ */
+@Join
+public class BoolGenerator implements Generator<Boolean> {
+    
+    @Override
+    public String getName() {
+        return "bool";
+    }
+    
+    @Override
+    public Boolean generate() {
+        return RandomUtil.randomInt(0, 1) == 1;
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 0;
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^bool$");
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGenerator.java
new file mode 100644
index 000000000..1286cbe8b
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGenerator.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.time.DateTimeException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.spi.Join;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Current time generator.
+ */
+@Join
+public class CurrentTimeGenerator implements Generator<String> {
+    
+    private static final String DEFAULT_FORMAT = "YYYY-MM-dd HH:mm:ss";
+    
+    private static final Logger LOG = LoggerFactory.getLogger(CurrentTimeGenerator.class);
+    
+    private String format;
+    
+    @Override
+    public String getName() {
+        return "current";
+    }
+    
+    @Override
+    public String generate() {
+        LocalDateTime now = LocalDateTime.now();
+        try {
+            return DateTimeFormatter.ofPattern(format).format(now);
+        } catch (DateTimeException e) {
+            LOG.warn("format fail,use default format :{}", DEFAULT_FORMAT);
+            return DateTimeFormatter.ofPattern(DEFAULT_FORMAT).format(now);
+        }
+        
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 0;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        if (params.size() >= 1) {
+            format = params.get(0);
+        } else {
+            format = DEFAULT_FORMAT;
+        }
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^current(\\|.+)?");
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EmailGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EmailGenerator.java
new file mode 100644
index 000000000..f4555e230
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EmailGenerator.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.apache.shenyu.plugin.mock.util.RandomUtil.randomInt;
+import static org.apache.shenyu.plugin.mock.util.RandomUtil.randomLowerLetterString;
+
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Random email address generator.
+ */
+@Join
+public class EmailGenerator implements Generator<String> {
+    
+    private static final String[] DOMAIN_SUFFIX = {"com", "org", "cn", "com.cn", "top", "edu",
+        "io"};
+    
+    @Override
+    public String getName() {
+        return "email";
+    }
+    
+    @Override
+    public String generate() {
+        return String.format("%s@%s.%s",
+            randomLowerLetterString(randomInt(5, 10)),
+            randomLowerLetterString(randomInt(3, 8)),
+            DOMAIN_SUFFIX[randomInt(0, DOMAIN_SUFFIX.length - 1)]);
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 0;
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^email$");
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EnStringGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EnStringGenerator.java
new file mode 100644
index 000000000..418c72f19
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/EnStringGenerator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.util.List;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.plugin.mock.util.RandomUtil;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Random english string generator.
+ */
+@Join
+public class EnStringGenerator implements Generator<String> {
+    
+    private int min;
+    
+    private int max;
+    
+    @Override
+    public String getName() {
+        return "zh";
+    }
+    
+    @Override
+    public String generate() {
+        return RandomStringUtils.random(RandomUtil.randomInt(min, max), 5, 129, true, false);
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 1;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        String[] range = params.get(0).split("-");
+        min = Integer.parseInt(range[0]);
+        max = Integer.parseInt(range[1]);
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^en\\|\\d+-\\d+$");
+    }
+    
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/PhoneGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/PhoneGenerator.java
new file mode 100644
index 000000000..490135deb
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/PhoneGenerator.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.plugin.mock.util.RandomUtil;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * 11-digit mobile number generator.
+ */
+@Join
+public class PhoneGenerator implements Generator<String> {
+    
+    @Override
+    public String getName() {
+        return "phone";
+    }
+    
+    @Override
+    public String generate() {
+        StringBuilder builder = new StringBuilder("1");
+        builder.append(RandomUtil.randomInt(3, 9));
+        for (int i = 0; i < 9; i++) {
+            builder.append(RandomUtil.randomInt(0, 9));
+        }
+        return builder.toString();
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 0;
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^phone$");
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGenerator.java
new file mode 100644
index 000000000..b0437a7a0
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGenerator.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.util.List;
+import java.util.Objects;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Random double value generator in the specified range.
+ */
+@Join
+public class RandomDoubleGenerator implements Generator<String> {
+    
+    private Double min;
+    
+    private Double max;
+    
+    private String format;
+    
+    @Override
+    public String getName() {
+        return "double";
+    }
+    
+    @Override
+    public String generate() {
+        Double result = (Math.random() * (max - min)) + min;
+        if (format != null) {
+            return String.format(format, result);
+        }
+        return String.valueOf(result);
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 1;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        String[] range = params.get(0).split("-");
+        min = Double.parseDouble(range[0]);
+        max = Double.parseDouble(range[1]);
+        if (params.size() == 2) {
+            format = Objects.equals(params.get(1), "") ? null : params.get(1);
+        }
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^double\\|\\d+(?:\\.\\d+)?-\\d+(?:\\.\\d+)?.*");
+    }
+}
+
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomIntGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomIntGenerator.java
new file mode 100644
index 000000000..42fbfee4e
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RandomIntGenerator.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.util.List;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.plugin.mock.util.RandomUtil;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Random int value generator in the specified range.
+ */
+@Join
+public class RandomIntGenerator implements Generator<Integer> {
+    
+    private int min;
+    
+    private int max;
+    
+    @Override
+    public String getName() {
+        return "int";
+    }
+    
+    @Override
+    public Integer generate() {
+        return RandomUtil.randomInt(min, max);
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 1;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        String[] range = params.get(0).split("-");
+        min = Integer.parseInt(range[0]);
+        max = Integer.parseInt(range[1]);
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^int\\|\\d+-\\d+$");
+    }
+    
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RangeDataGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RangeDataGenerator.java
new file mode 100644
index 000000000..90527d2ac
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/RangeDataGenerator.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.plugin.mock.util.RandomUtil;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Specify the in-list data generator.
+ */
+@Join
+public class RangeDataGenerator implements Generator<String> {
+    
+    private List<String> data;
+    
+    @Override
+    public String getName() {
+        return "list";
+    }
+    
+    @Override
+    public String generate() {
+        return data.get(RandomUtil.randomInt(0, data.size() - 1));
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 0;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        String rangeData = params.get(0).replaceAll("\\[(.+)]", "$1");
+        data = Arrays.stream(rangeData.split("(?<!\\\\),"))
+            .map(data -> data.replace("\\,", ","))
+            .collect(Collectors.toList());
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        boolean matches = rule.matches("^list\\|\\[.+]$");
+        if (matches) {
+            String candidateData = rule.substring(6, rule.length() - 1);
+            return !candidateData.matches("^\\s+$");
+        }
+        return false;
+    }
+}
+
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/ZhStringGenerator.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/ZhStringGenerator.java
new file mode 100644
index 000000000..ee11a1796
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/ZhStringGenerator.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.util.List;
+import java.util.Random;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.spi.Join;
+
+/**
+ * Random length Chinese string generator.
+ */
+@Join
+public class ZhStringGenerator implements Generator<String> {
+    
+    private int min;
+    
+    private int max;
+    
+    @Override
+    public String getName() {
+        return "zh";
+    }
+    
+    @Override
+    public String generate() {
+        Random random = new Random();
+        int len = random.nextInt(max - min - 1) + min;
+        return RandomStringUtils.random(len, 0x4e00, 0x9fa5, false, false);
+    }
+    
+    @Override
+    public int getParamSize() {
+        return 1;
+    }
+    
+    @Override
+    public void initParam(final List<String> params) {
+        String[] range = params.get(0).split("-");
+        min = Integer.parseInt(range[0]);
+        max = Integer.parseInt(range[1]);
+    }
+    
+    @Override
+    public boolean match(final String rule) {
+        return rule.matches("^zh\\|\\d+-\\d+$");
+    }
+    
+}
+
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/GeneratorFactory.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/GeneratorFactory.java
new file mode 100644
index 000000000..41ef7ef05
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/GeneratorFactory.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.util;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.shenyu.plugin.base.mock.Generator;
+import org.apache.shenyu.spi.ExtensionLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GeneratorFactory.
+ */
+public final class GeneratorFactory {
+    
+    /**
+     * Regular expression to extract placeholders.
+     */
+    private static final Pattern RULE_PATTERN = Pattern
+        .compile("(\\$\\{.+?})", Pattern.MULTILINE);
+    
+    private static final Logger LOG = LoggerFactory.getLogger(GeneratorFactory.class);
+    
+    /**
+     * Regular expression to extract rule content.
+     */
+    private static final Pattern RULE_CONTENT_PATTERN = Pattern
+        .compile("^\\$\\{(.+?)}$", Pattern.MULTILINE);
+    
+    private GeneratorFactory() {
+    }
+    
+    /**
+     * New instance mock data generator.
+     *
+     * @param ruleName rule name
+     * @param rule     full rule content
+     * @return generator
+     */
+    public static Generator<?> newInstance(final String ruleName, final String rule) {
+        try {
+            return ExtensionLoader.getExtensionLoader(Generator.class).getJoin(ruleName);
+        } catch (IllegalArgumentException e) {
+            LOG.warn("{} can not parse,please check", rule);
+        }
+        return null;
+    }
+    
+    private static Object generate(final String rule) {
+        final Matcher matcher = RULE_CONTENT_PATTERN.matcher(rule);
+        if (matcher.find()) {
+            String ruleContent = matcher.group(1);
+            String ruleName = ruleContent.split("\\|")[0];
+            Generator<?> generator = newInstance(ruleName, rule);
+            if (generator == null || !generator.match(ruleContent)) {
+                return rule;
+            }
+            generator.parseRule(ruleContent);
+            return generator.generate();
+        } else {
+            return rule;
+        }
+    }
+    
+    /**
+     * replace placeholder in content.
+     *
+     * @param content response content.
+     * @return replace the content after the placeholder.
+     */
+    public static String dealRule(final String content) {
+        String afterDeal = content;
+        final Matcher matcher = RULE_PATTERN.matcher(afterDeal);
+        while (matcher.find()) {
+            String placeHolder = matcher.group(0);
+            Object generateData = generate(placeHolder);
+            if (Objects.equals(generateData, placeHolder)) {
+                continue;
+            }
+            String toString = String.valueOf(generateData);
+            if (generateData instanceof String) {
+                toString = String.format("\"%s\"", toString);
+            }
+            placeHolder = placeHolder.replaceAll("([$|{}\\]\\[])", "\\\\$1");
+            afterDeal = afterDeal.replaceFirst(placeHolder, toString);
+        }
+        return afterDeal;
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/RandomUtil.java b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/RandomUtil.java
new file mode 100644
index 000000000..e23eaebb2
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/util/RandomUtil.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.util;
+
+import java.util.concurrent.ThreadLocalRandom;
+import org.apache.commons.lang3.RandomStringUtils;
+
+/**
+ * Random Util.
+ */
+public class RandomUtil {
+    
+    /**
+     * Randomly generate integers.
+     *
+     * @param min min included
+     * @param max max included
+     * @return random int
+     */
+    public static int randomInt(final int min, final int max) {
+        ThreadLocalRandom random = ThreadLocalRandom.current();
+        return random.nextInt(max - min + 1) + min;
+    }
+    
+    /**
+     * Generate a  string containing only lowercase letters.
+     *
+     * @param length length
+     * @return string
+     */
+    public static String randomLowerLetterString(final int length) {
+        return RandomStringUtils.random(length, 96, 123, true, false);
+    }
+    
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/main/resources/META-INF/shenyu/org.apache.shenyu.plugin.base.mock.Generator b/shenyu-plugin/shenyu-plugin-mock/src/main/resources/META-INF/shenyu/org.apache.shenyu.plugin.base.mock.Generator
new file mode 100644
index 000000000..8382aeb1e
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/main/resources/META-INF/shenyu/org.apache.shenyu.plugin.base.mock.Generator
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+bool=org.apache.shenyu.plugin.mock.generator.BoolGenerator
+current=org.apache.shenyu.plugin.mock.generator.CurrentTimeGenerator
+email=org.apache.shenyu.plugin.mock.generator.EmailGenerator
+en=org.apache.shenyu.plugin.mock.generator.EnStringGenerator
+phone=org.apache.shenyu.plugin.mock.generator.PhoneGenerator
+double=org.apache.shenyu.plugin.mock.generator.RandomDoubleGenerator
+int=org.apache.shenyu.plugin.mock.generator.RandomIntGenerator
+list=org.apache.shenyu.plugin.mock.generator.RangeDataGenerator
+zh=org.apache.shenyu.plugin.mock.generator.ZhStringGenerator
+
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/BoolGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/BoolGeneratorTest.java
new file mode 100644
index 000000000..4da962ceb
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/BoolGeneratorTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link BoolGenerator}.
+ */
+public final class BoolGeneratorTest {
+    
+    private final BoolGenerator boolGenerator = new BoolGenerator();
+    
+    @Test
+    public void testGenerate() {
+        boolGenerator.parseRule("bool");
+        Boolean generate = boolGenerator.generate();
+        Assertions.assertNotNull(generate);
+        
+    }
+    
+    @Test
+    public void testMatch() {
+        assertTrue(boolGenerator.match("bool"));
+        assertFalse(boolGenerator.match("boolean"));
+        
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGeneratorTest.java
new file mode 100644
index 000000000..51f5cbe7b
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/CurrentTimeGeneratorTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link CurrentTimeGenerator}.
+ */
+public final class CurrentTimeGeneratorTest {
+    
+    private final CurrentTimeGenerator generator = new CurrentTimeGenerator();
+    
+    @Test
+    public void testGenerate() {
+        generator.parseRule("${current}");
+        Assertions.assertEquals(generator.generate(), currentTime("YYYY-MM-dd HH:mm:ss"));
+        generator.parseRule("current|YYYY-MM-dd");
+        Assertions.assertEquals(generator.generate(), currentTime("YYYY-MM-dd"));
+        
+    }
+    
+    private String currentTime(final String format) {
+        return new SimpleDateFormat(format).format(new Date());
+    }
+    
+    @Test
+    public void testMatch() {
+        Assertions.assertTrue(generator.match("current"));
+        Assertions.assertFalse(generator.match("current|"));
+        Assertions.assertTrue(generator.match("current|YYYY-MM-dd"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EmailGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EmailGeneratorTest.java
new file mode 100644
index 000000000..7e299bb76
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EmailGeneratorTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link EmailGenerator}.
+ */
+public final class EmailGeneratorTest {
+    
+    private final EmailGenerator generator = new EmailGenerator();
+    
+    @Test
+    public void testGenerate() {
+        generator.parseRule("email");
+        String email = generator.generate();
+        assertNotNull(email);
+    }
+    
+    @Test
+    public void match() {
+        assertTrue(generator.match("email"));
+        assertFalse(generator.match("mail"));
+        assertFalse(generator.match("Email"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EnStringGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EnStringGeneratorTest.java
new file mode 100644
index 000000000..cad289806
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/EnStringGeneratorTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link EnStringGenerator}.
+ */
+public final class EnStringGeneratorTest {
+    
+    private final EnStringGenerator generator = new EnStringGenerator();
+    
+    @Test
+    public void testGenerate() {
+        int max = 10;
+        int min = 5;
+        generator.parseRule("en|" + min + "-" + max);
+        String enString = generator.generate();
+        assertTrue(enString.matches("[a-zA-Z]{" + min + "," + max + "}"));
+    }
+    
+    @Test
+    public void testMatch() {
+        assertTrue(generator.match("en|10-12"));
+        assertFalse(generator.match("en"));
+        assertFalse(generator.match("en|"));
+        assertFalse(generator.match("en|10.1-12.1"));
+        assertFalse(generator.match("en|10"));
+        assertFalse(generator.match("en|-10"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/PhoneGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/PhoneGeneratorTest.java
new file mode 100644
index 000000000..9efb52ce4
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/PhoneGeneratorTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link PhoneGenerator }.
+ *
+ * @date 2022/6/20 14:48
+ */
+public final class PhoneGeneratorTest {
+    
+    private final PhoneGenerator generator = new PhoneGenerator();
+    
+    @Test
+    void testGenerate() {
+        generator.parseRule("phone");
+        String phone = generator.generate();
+        assertTrue(phone.matches("^1[3-9]\\d{9}$"));
+    }
+    
+    @Test
+    void match() {
+        assertTrue(generator.match("phone"));
+        assertFalse(generator.match("mobile"));
+        
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGeneratorTest.java
new file mode 100644
index 000000000..e64630de4
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomDoubleGeneratorTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link RandomDoubleGenerator}.
+ */
+public final class RandomDoubleGeneratorTest {
+    
+    private final RandomDoubleGenerator generator = new RandomDoubleGenerator();
+    
+    @Test
+    public void generate() {
+        generator.parseRule("double|10.5-12.0");
+        String doubleValue = generator.generate();
+        assertNotNull(doubleValue);
+        generator.parseRule("double|10.5-12.0|¥%.2f");
+        String formated = generator.generate();
+        assertAll(
+            () -> assertNotNull(formated),
+            () -> assertTrue(formated.matches("^¥\\d+.\\d{2}$"))
+        );
+        
+    }
+    
+    @Test
+    public void match() {
+        assertTrue(generator.match("double|10-15"));
+        assertTrue(generator.match("double|10.1-15"));
+        assertTrue(generator.match("double|10.1-15.2"));
+        assertTrue(generator.match("double|10.1-15.2|"));
+        assertTrue(generator.match("double|10.1-15.2|%.2f"));
+        assertFalse(generator.match("double"));
+        assertFalse(generator.match("double|10.2.1-"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomIntGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomIntGeneratorTest.java
new file mode 100644
index 000000000..ef1248658
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RandomIntGeneratorTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link RandomIntGenerator}.
+ */
+public final class RandomIntGeneratorTest {
+    
+    private final RandomIntGenerator generator = new RandomIntGenerator();
+    
+    @Test
+    public void generate() {
+        int min = 10;
+        int max = 15;
+        generator.parseRule(String.format("int|%d-%d", min, max));
+        Integer generate = generator.generate();
+        assertTrue(generate != null && generate >= min && generate <= max);
+    }
+    
+    @Test
+    public void match() {
+        assertTrue(generator.match("int|10-15"));
+        assertFalse(generator.match("int|10.0-15"));
+        assertFalse(generator.match("int"));
+        assertFalse(generator.match("int|"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RangeDataGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RangeDataGeneratorTest.java
new file mode 100644
index 000000000..e39b37bad
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/RangeDataGeneratorTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Objects;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link RangeDataGenerator}.
+ */
+public final class RangeDataGeneratorTest {
+    
+    private final RangeDataGenerator generator = new RangeDataGenerator();
+    
+    @Test
+    public void generate() {
+        generator.parseRule("list|[shenyu,gateway]");
+        String rangeData = generator.generate();
+        assertTrue(Objects.equals("shenyu", rangeData) || Objects.equals("gateway", rangeData));
+    }
+    
+    @Test
+    public void testListDataContainComma() {
+        generator.parseRule("list|[shen\\,yu,gate\\,way]");
+        String rangeData = generator.generate();
+        assertTrue(Objects.equals("shen,yu", rangeData) || Objects.equals("gate,way", rangeData));
+    }
+    
+    @Test
+    public void match() {
+        assertTrue(generator.match("list|[shen\\,yu,gate\\,way]"));
+        assertTrue(generator.match("list|[shenyu,gateway]"));
+        assertFalse(generator.match("list|[shenyu,gateway"));
+        assertFalse(generator.match("list|[]"));
+        assertFalse(generator.match("list|[ ]"));
+        
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/ZhStringGeneratorTest.java b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/ZhStringGeneratorTest.java
new file mode 100644
index 000000000..45a3478b1
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-mock/src/test/java/org/apache/shenyu/plugin/mock/generator/ZhStringGeneratorTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.mock.generator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * The test case for {@link ZhStringGenerator}.
+ *
+ * @date 2022/6/20 15:44
+ */
+public final class ZhStringGeneratorTest {
+    
+    private final ZhStringGenerator generator = new ZhStringGenerator();
+    
+    @Test
+    public void generate() {
+        int minLength = 10;
+        int maxLength = 20;
+        generator.parseRule(String.format("zh|%d-%d", minLength, maxLength));
+        String generate = generator.generate();
+        assertTrue(
+            generate != null && generate.length() >= minLength && generate.length() <= maxLength);
+    }
+    
+    @Test
+    public void match() {
+        assertTrue(generator.match("zh|10-15"));
+        assertFalse(generator.match("zh"));
+        assertFalse(generator.match("zh|"));
+        assertFalse(generator.match("zh|10.1-15"));
+    }
+}