mock测试【创建服务、fiddler、单元测试】 、开发mock平台

mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。

一、创建服务的方式——flask、django

import flask
from flask import request

# 创建接口后台服务
server = flask.Flask(__name__)


@server.route('/', methods=['get', 'post'])
def demo():
    # 获取get请求参数
    arg = request.args.get("key")
    # post 获取表单请求数据
    form = request.form.get("key", type=str, default=None)

    # 获取所有请求参数,不能获取json
    values = request.values.get("key")
    # 获取请求json
    json = request.get_json()

    print("arg", arg)
    print("form", form)
    print("values", values)
    print("json", json)
    return "你想返回的内容"


server.run(host="127.0.0.1", port=9000, debug=True)

  flask是python的一个轻量级web框架,比较简单。

  django稍微比较复杂,可以参考:https://blog.csdn.net/weixin_30268071/article/details/98903930,这个已经做成了一个小项目的形式

遇到的问题:

1、post请求,结果获取参数的时候,却是如下方式

request.values.get("key")

2、post请求,因为Content-Type的问题,通过如下方式解决

request.get_json(force=True)

3、get请求,按道理参数是?后面拼接字段名=字段值,但是遇到的是直接放在/后面,解决示例如下

@server.route('/SeonRestService/email-api/v2.0/<email>', methods=['get'])
def seon_email_api(email):
    """https://api.seon.io"""
    print("seon_email_api服务,email是:", email)

4、容器中安装vim

先执行:apt-get update

再执行:apt-get install vim

5、获取请求头,请求url,请求方法等信息都有对应的方法

6、接口返回的类型

https://www.cnblogs.com/xihuanniya/p/10451732.html

https://blog.csdn.net/qq_22034353/article/details/88758395

二、创建服务的方式—— tornado

  tornado也是python自带的一个轻量级web框架,是一个群友提供的一个mock示例时,了解到的这个框架,可以参考:https://blog.csdn.net/xc_zhou/article/details/80637714

import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler):
    '''http服务端'''

    def get(self):
        '''get请求'''
        a = self.get_argument('a')
        self.write({'我有这么多钱': int(a)})

    def post(self):
        '''post请求'''
        h = self.request.headers
        u = self.request.uri
        b = self.request.body
        print("h", h)
        print("u", u)
        print("b", b)

        # 下面2行代码是设置返回的信息,目前没有想到使用场景
        # self.set_header('Content-Type', 'application/json; charset=UTF-8;')
        # self.set_status(200, '失败')

        self.write("返回的内容")

if __name__ == '__main__':
    application = tornado.web.Application([('/', MainHandler)])
    # 默认host: 127.0.0.1
    application.listen(address="127.0.0.2", port=8866)
    tornado.ioloop.IOLoop.instance().start()

    #和上面启动方式不同的地方就多了参数:decompress_request=True
    #在有这个配置项的时候,如果post请求的报文头部有说明编码方式是 gzip时,tornado将会对这个请求进行解压操作
    # http_server = tornado.httpserver.HTTPServer(application, decompress_request=True)
    # http_server.listen(8866)
    # tornado.ioloop.IOLoop.instance().start()

 

三、fiddler的mock 

实际上是劫持的方式给的自定义响应,如下图,在AutoResponder选项卡下添加规则即可

四、unittest中的mock

from unittest.mock import patch
from unittest import mock
import unittest


class C:
    def a(self):
        return 666

    def b(self):
        return 666


class TestXXX(unittest.TestCase):
    """单元测试的2种mock方式
       mock不能凭空创建属性a,只能应用于对象逻辑还没完成但是需要这个对象的返回信息
       感觉意义不是很大"""

    @patch.object(C, 'b')
    @patch.object(C, 'a')
    def test_xxx1(self, a, b):
        # 注意测试方法中的参数和装饰器的参数对应关系
        a.return_value = 20
        b.return_value = 30
        c = C()
        print("test_xxx1", c.a(), c.b())

    def test_xxx2(self):
        c = C()
        c.a = mock.Mock(return_value=20)
        print("test_xxx2", c.a())


if __name__ == '__main__':
    unittest.main()

 五、java中的mock

package yin.service;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
// mock用到的2个包
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import yin.dao.StudentDao;
import yin.domain.Student;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class StudentServiceTest {

    @Autowired
    StudentService studentService;

    @MockBean
    StudentDao studentDao;

    @BeforeEach
    void setUp() {
        // 下面studentService.getStudentById(1)中会用studentDao.getStudentById(1)
        Mockito.when(studentDao.getStudentById(1)).
                thenReturn(new Student(1,10,"whitewall"));
    }

    @Test
    void getStudentById() {
        Student student = studentService.getStudentById(1);
        assertNotNull(student);
        assertEquals(student.getAge(),12);
    }
}

 四、开发mock平台

get路径  https://域名/mock/cmdb/project_A/interface_A/get?page=1&pageSize=10
post路径 https://域名/mock/cmdb/project_A/interface_B/post

1、代码思路

mock接口格式(接收get、post):@app.route('/mock/<project>/<interface>/<request_type>')

先获取项目名/接口名/请求类型,判断是否在数据库中有匹配数据
然后判断请求类型
  post请求会去获取请求体中的参数,然后跟进数据库中比较类型,去判断参数
  get请求会去获取url后续的参数,然后跟进数据库中比较类型,去判断参数

2、建表

(1)项目表(项目id,项目名,项目描述,创建人,创建时间,修改人,修改时间)
(2)接口表(项目id,接口名,接口描述,场景说明,请求类型,比较类型(包含、恒等),入参,期望出参,是否有效,创建人,修改人,修改人,修改时间)

3、页面
(1)项目管理:项目增删查改
(2)接口管理:接口增删查改
  a、一个接口可以对应多个场景
  b、查询功能:项目查询、接口名、请求类型、是否生效(默认生效)
    查询结果: 项目名、接口名、接口描述、场景说明、请求类型、入参、期望出参
    查询结果操作:失效接口显示生效按钮、生效接口显示失效按钮、详情、编辑
  c、新建、编辑功能:对应接口表的信息

posted @ 2021-05-16 12:47  whitewall  阅读(183)  评论(1编辑  收藏  举报