• 基于Spring Boot框架开发的一个Mock


    背景:在项目后端接口开发还未完成,我们无法进行自动化接口用例的调试,希望与开发同步完成接口自动化用例的编写及调试,待项目转测后,可以直接跑自动化用例,提高测试效率.

    选用的maven + Spring Boot框架,代码的示例自己随便构造的, 由于实际项目接口没有做cookie的校验, 所以示例接口没有添加cookie和做cookie校验,后续有需求再研究...直接上代码

    pom.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0"
     3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5     <modelVersion>4.0.0</modelVersion>
     6 
     7     <groupId>LMock</groupId>
     8     <artifactId>spring-boot-LMock</artifactId>
     9     <version>1.0.0</version>
    10 
    11     <parent>
    12         <groupId>org.springframework.boot</groupId>
    13         <artifactId>spring-boot-starter-parent</artifactId>
    14         <version>2.0.2.RELEASE</version>
    15     </parent>
    16 
    17     <dependencies>
    18         <dependency>
    19             <groupId>org.springframework.boot</groupId>
    20             <artifactId>spring-boot-starter-web</artifactId>
    21         </dependency>
    22         <dependency>
    23             <groupId>org.projectlombok</groupId>
    24             <artifactId>lombok</artifactId>
    25             <version>1.16.14</version>
    26         </dependency>
    27         <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    28         <dependency>
    29             <groupId>com.alibaba</groupId>
    30             <artifactId>fastjson</artifactId>
    31             <version>1.2.49</version>
    32         </dependency>
    33     </dependencies>
    34 
    35     <build>
    36         <plugins>
    37             <plugin>
    38                 <groupId>org.apache.maven.plugins</groupId>
    39                 <artifactId>maven-compiler-plugin</artifactId>
    40                 <configuration>
    41                     <source>1.8</source>
    42                     <target>1.8</target>
    43                 </configuration>
    44             </plugin>
    45 
    46             <plugin>
    47                 <groupId>org.springframework.boot</groupId>
    48                 <artifactId>spring-boot-maven-plugin</artifactId>
    49                 <configuration>
    50                     <mainClass>Application</mainClass>
    51                 </configuration>
    52                 <executions>
    53                     <execution>
    54                         <goals>
    55                             <goal>repackage</goal>
    56                         </goals>
    57                     </execution>
    58                 </executions>
    59             </plugin>
    60 
    61             <plugin>
    62                 <artifactId>maven-compiler-plugin</artifactId>
    63                 <configuration>
    64                     <source>1.8</source>
    65                     <target>1.8</target>
    66                     <encoding>UTF-8</encoding>
    67                     <compilerArguments>
    68                         <extdirs>${project.basedir}/lib</extdirs>
    69                     </compilerArguments>
    70                 </configuration>
    71             </plugin>
    72 
    73         </plugins>
    74     </build>
    75 
    76 </project>

    resources目录下面的配置文件application.properties, 注意:该文件要utf8编码格式,不然中文会乱码

    server.port=${port:8889}
    logging.file=lmock.log
    logging.path=logs #userInfo u.name=张三 u.sex=男 u.age=20 u.addr=北京市紫禁城 u.status=0 u.uid=123456789 #loginInfo login.account=123456789@qq.com,987654321@163.com login.pwd=123456 #responsemsg ERROR.CODE.1001={"resultCode": 1001, "msg": "用户名或者密码错误"}

    logback.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <configuration>
     4     <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
     5     <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n"/>
     6     <property name="LOG_PATH" value="${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}"/>
     7     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     8         <file>${LOG_PATH}/${LOG_FILE}</file>
     9         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    10             <fileNamePattern>${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}</fileNamePattern>
    11         </rollingPolicy>
    12         <encoder charset="UTF-8">
    13             <pattern>${FILE_LOG_PATTERN}</pattern>
    14         </encoder>
    15     </appender>
    16 
    17 
    18     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    19         <encoder>
    20             <pattern>${FILE_LOG_PATTERN}</pattern>
    21         </encoder>
    22     </appender>
    23 
    24     <appender name="CRAWLER_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    25         <file>${LOG_PATH}/event.log</file>
    26         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    27             <fileNamePattern>${LOG_PATH}/event.%d{yyyy-MM-dd}.log</fileNamePattern>
    28             <maxHistory>30</maxHistory>
    29         </rollingPolicy>
    30         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    31             <pattern>%msg%n</pattern>
    32         </encoder>
    33     </appender>
    34 
    35     <logger name="com.business.intelligence.util.CrawlerLogger" level="INFO" additivity="false">
    36         <appender-ref ref="CRAWLER_LOG"/>
    37     </logger>
    38 
    39     <root level="INFO">
    40         <appender-ref ref="STDOUT"/>
    41         <appender-ref ref="FILE"/>
    42     </root>
    43 
    44 </configuration>

    入口程序:Application.java

     1 import org.springframework.boot.SpringApplication;
     2 import org.springframework.boot.autoconfigure.SpringBootApplication;
     3 import org.springframework.context.annotation.ComponentScan;
     4 
     5 @SpringBootApplication
     6 @ComponentScan("com.lmock")
     7 public class Application {
     8 
     9     public static void main(String[] args) {
    10         SpringApplication.run(Application.class, args);
    11     }
    12 }

    javabean的类, LoginInfo.java  UserInfo.java

     1 package com.lmock.bean;
     2 
     3 import lombok.Data;
     4 
     5 @Data
     6 public class UserInfo {
     7     private String name;
     8     private String sex;
     9     private int age;
    10     private String addr;
    11     private int status;
    12     private String uid;
    13 
    14     @Override
    15     public String toString() {
    16         return "{"name": "" + name +
    17                 "", "sex": "" + sex +
    18                 "", "age": " + age +
    19                 ", "addr": "" + addr +
    20                 "", "status": " + status +
    21                 ", "uid": "" + uid +
    22                 ""}";
    23     }
    24 }
    1 package com.lmock.bean;
    2 
    3 import lombok.Data;
    4 
    5 @Data
    6 public class LoginInfo {
    7     private String account;
    8     private String pwd;
    9 }

    配置文件数据处理类, ReadConfig.java

     1 package com.lmock.data;
     2 
     3 import com.lmock.bean.UserInfo;
     4 
     5 import java.io.UnsupportedEncodingException;
     6 import java.util.Arrays;
     7 import java.util.List;
     8 import java.util.Locale;
     9 import java.util.ResourceBundle;
    10 
    11 public class ReadConfig {
    12     private static ResourceBundle bundle = ResourceBundle.getBundle("application", Locale.PRC);
    13 
    14     public static String login_account = bundle.getString("login.account");
    15     public static List<String> login_account_list = Arrays.asList(login_account.split(","));
    16     public static String login_pwd = bundle.getString("login.pwd");
    17     public static String ERROR_CODE_1001 = transcoding("ERROR.CODE.1001");
    18 
    19     public String readUserInfo() {
    20         UserInfo ui = new UserInfo();
    21         ui.setName(transcoding("u.name"));
    22         ui.setSex(transcoding("u.sex"));
    23         ui.setAge(Integer.parseInt(transcoding("u.age")));
    24         ui.setAddr(transcoding("u.addr"));
    25         ui.setStatus(Integer.parseInt(transcoding("u.status")));
    26         ui.setUid(transcoding("u.uid"));
    27         return ui.toString();
    28     }
    29 
    30     private static String transcoding(String key) {
    31         try {
    32             return new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF8");
    33         } catch (UnsupportedEncodingException e) {
    34             return bundle.getString(key);
    35         }
    36     }
    37 
    38 }

    接口实现类, PostDemo.java

     1 package com.lmock.server;
     2 
     3 import com.lmock.bean.LoginInfo;
     4 import com.lmock.bean.UserInfo;
     5 import com.lmock.data.ReadConfig;
     6 import org.springframework.web.bind.annotation.RequestBody;
     7 import org.springframework.web.bind.annotation.RequestMapping;
     8 import org.springframework.web.bind.annotation.RequestMethod;
     9 import org.springframework.web.bind.annotation.RestController;
    10 
    11 @RestController
    12 public class PostDemo {
    13     @RequestMapping(value = "/v1/getUserInfo", method = RequestMethod.POST)
    14     public String getUserInfo(@RequestBody LoginInfo loginInfo){
    15         UserInfo ui;
    16         if(loginInfo.getAccount().equals("123456789@qq.com") && loginInfo.getPwd().equals("123456")){
    17             ui = new UserInfo();
    18             ui.setName("张三");
    19             ui.setAge(20);
    20             ui.setAddr("北京市紫禁城");
    21             ui.setSex("男");
    22             ui.setStatus(0);
    23             ui.setUid("123456789");
    24             return ui.toString();
    25         }
    26         return "{"resultCode": 1001, "msg": "用户名或者密码错误"}";
    27     }
    28 
    29     @RequestMapping(value = "/v2/getUserInfo", method = RequestMethod.POST)
    30     public String getUserInfoWithConfig(@RequestBody LoginInfo loginInfo){
    31         if(ReadConfig.login_account_list.contains(loginInfo.getAccount()) && loginInfo.getPwd().equals(ReadConfig.login_pwd)){
    32                 return new ReadConfig().readUserInfo();
    33         }
    34         return ReadConfig.ERROR_CODE_1001;
    35     }
    36 }

    最后决定用V2的方式写Mock, 这样接口参数校验的逻辑写好后, 只需要修改properties配置文件数据即可, 这样就可以当作一个测试桩, 也可以把桩要返回的数据写成json文件,这里没有去研究了, 个人觉得写成配置文件也挺好的,特别是需要多个数据, 可以利用List

    启动Mock后,接口请求的效果

  • 相关阅读:
    在JBuilder8中使用ANT
    协程初探
    JavaScript编写了一个计时器
    Codeforces Round #272 (Div. 1)D(字符串DP)
    UI測试内容
    我为什么做程序猿訪谈录
    使用Java高速实现进度条
    做web项目时对代码改动后浏览器端不生效的应对方法(持续更新)
    将markdown格式转化为bootstrap风格html
    char* 和char[]的差别
  • 原文地址:https://www.cnblogs.com/andrew209/p/9539286.html
Copyright © 2020-2023  润新知