Vue learning (eight) - introduce mock for testing

foreword

According to the architecture design idea of ​​separating the front and back ends, usually the front end calls the back end interface through axios. If the back-end interface is not written, how can the front-end test it? At this time, it is necessary to introduce mock. Mock intercepts front-end requests and generates test data. This looks like calling the backend interface. Although mock can't realize any business functions, but as a front-end development, the introduction of mock is also essential.

introduce mock

Since the function of the mock is originally used for the corresponding ajax call, we continue to use the project built in " Vue Learning (7) - Introducing Axios " as an example. Introduce mock on top of it and use it.

First install the mock.js dependency in the project

npm install mockjs --save

Create a new mock directory under the src directory, and create a new file index.js under the mock directory

import Mock from 'mockjs';

Mock.mock('/api/hello', {
  'code': 200,
  'name': 'test helloController', 
});

Mock.mock('/api/hello/name', 'post', function(param){
  let data = param.body
  return 'hello ' + data
});

Here we write the two interfaces /hello and /hello/name corresponding to the returned data. Here is only a simple usage method, please refer to mockjs official website for other usage methods.

Then introduce in main.js

import Vue from 'vue'
import App from './App.vue'

import axios from 'axios'
Vue.prototype.$axios = axios
Vue.config.productionTip = false

require('./mock');

new Vue({
  render: h => h(App),
}).$mount('#app')

Line 8 introduces the mock. In this way, when we send a request to the background through axios, the mock will intercept the request and return the previously set data. It looks like the front end really calls the back end interface. It is convenient for our subsequent development and debugging.

Then start the program, click the button to test, and click f12 to view the output. Pay attention to only look at the console output, not the network, because after the mock is intercepted, the network request is not sent. This part is not shown.

Randomly generated data for mocks

A major feature of mock is to generate data randomly. If you have to write the data one by one by yourself, especially if there are many fields and the sample required for the test is large, it will be very troublesome. For example, test the effectiveness of pagination, whether the effect of query filtering is correct, and so on.

Here it is displayed through a table, so the table component of element ui needs to be introduced. Add a dependency on element ui under the project:

npm install element-ui --save

Introduced in main.js, modify main.js

import Vue from 'vue'
import App from './App.vue'

import axios from 'axios'
Vue.prototype.$axios = axios
Vue.config.productionTip = false

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

require('./mock');

new Vue({
  render: h => h(App),
}).$mount('#app')

Lines 8-11 introduce element-ui.

Next, create a new api call, and create a new score.js in the src/api directory

import request from '../utils/request'

export function all() {
  return request({
    url: '/score/all',
    method: 'get'
  })
}

Here we define an api as all, which means to get all the data, in order to distinguish it from the subsequent paging list calls.

Next is the key point , add mock random data, create a new mockscore.js in the src/mock directory

import Mock from 'mockjs';

Mock.mock('/api/score/all', {
    'data|10': [
      {'id|+1':1, 'name':'@name', 'score|70-100':100}
    ]
});

The above fully reflects the characteristics of mock randomly generated data. The above means to generate an array of 10 elements named data, the id field starts at 1 and increments by 1; the name field randomly generates a name; the score field randomly generates a number of 70-100. There are many ways for mock to generate random data. For specific rules, please refer to the official website.

We create a new page, the page list displays the list data, and create a new Score.vue under src/components

<template>
  <div>
     <template>
    <el-table :data="tableData" style="width: 50%">
      <el-table-column prop="id" label="id" width="180"></el-table-column>
      <el-table-column prop="name" label="姓名" width="180"></el-table-column>
      <el-table-column prop="score" label="分数" width="180"></el-table-column>
    </el-table>
  </template>
  </div>
</template>

<script>
import { all } from '@/api/score.js'
require('../mock/mockscore.js');


export default {
  name: 'MyTable',
  data() {
    return {
      tableData: [],
    }
  },
  created(){
    all().then(res => {
      this.tableData = res.data
    })
  },
  methods: {
  }
}
</script>

<style scoped>
</style>

A simple list is displayed here. The all method is called when the page is loaded, and the data returned by the call is set to the tableData variable.

Finally, in App.vue, we changed the reference to the HelloWord module to the Score module (just to test the display effect, normal projects should add routes and access the corresponding url). Modify App.vue

<template>
  <div id="app">
    <Score/>
  </div>
</template>

<script>
import Score from './components/Score.vue'

export default {
  name: 'App',
  components: {
    Score
  }
}
</script>

<style>
</style>

Start the project and visit localhost:8080:

You can see that our random data is generated. The next step is to add, delete, check and modify.

Mock additions, deletions, checks and modifications

It is relatively troublesome to add, delete, check, and modify mock data, because usually adding, deleting, checking, and modifying is done by the database, and it is done with one instruction. But in the mock, we have to maintain it ourselves. Especially when querying, we have to filter the data by ourselves. If it involves sorting or something, it will be even more troublesome. Here is a simpler case. Due to the relatively large amount of code, it is not well written, and only shows how to use it.

First of all, make some preparations and write the api for adding, deleting, checking and modifying functions. Modify score.js under src/api

import request from '../utils/request'

export function all() {
  return request({
    url: '/score/all',
    method: 'get'
  })
}

export function add(param) {
  return request({
    url: '/score/add',
    method: 'post',
    data: param
  })
}

export function update(param) {
  return request({
    url: '/score/update',
    method: 'post',
    data: param
  })
}

export function del(id) {
  return request({
    url: '/score/delete',
    method: 'post',
    data: id
  })
}

export function list(param) {
  return request({
    url: '/score/list',
    method: 'post',
    data: param
  })
}

Then modify src/mock/mockscore.js, add adding, deleting, checking and modifying methods

import Mock from 'mockjs';

const StudentData = Mock.mock({
    'data|10': [
      {'id|+1':1, 'name':'@name', 'score|70-100':100}
    ]
});

Mock.mock('/api/score/all', 'get', function(){
  const resMsg = {
    'code': 200,
    'data': StudentData.data,
    'msg': '获取成功'
  }
  return resMsg
})

Mock.mock('/api/score/add', 'post', function(data){
  let student = JSON.parse(data.body)
  student.id = parseInt(student.id)
  student.score = parseInt(student.score)
  StudentData.data.push(student)
  const resMsg = {
    'code': 200,
    'msg': '添加成功'
  }
  return resMsg
});

Mock.mock('/api/score/list', 'post', function(data){
  let resData = []
  let queryParam = JSON.parse(data.body)
  for(let index in StudentData.data){
    if(queryParam.id == undefined || queryParam.id == null || queryParam.id == ''){
      resData.push(StudentData.data[index])
    }else{
      if(StudentData.data[index].id == queryParam.id){
        resData.push(StudentData.data[index])
      }
    }
  }
  const resMsg = {
    'code': 200,
    'data': resData,
    'msg': '查询成功'
  }
  return resMsg
});

Mock.mock('/api/score/update', 'post', function(data){
  let student = JSON.parse(data.body)
  student.id = parseInt(student.id)
  student.score = parseInt(student.score)
  for(let index in StudentData.data){
    if(StudentData.data[index].id == student.id){
      StudentData.data[index] = student
    }
  }
  const resMsg = {
    'code': 200,
    'msg': '修改成功'
  }
  return resMsg
});

Mock.mock('/api/score/delete', 'post', function(data){
  let id = parseInt(JSON.parse(data.body))
  for(let index in StudentData.data){
    if(StudentData.data[index].id == id){
      StudentData.data.splice(index, 1)
      break
    }
  }
  const resMsg = {
    'code': 200,
    'msg': '删除成功'
  }
  return resMsg
});

The idea is very simple. For adding, it is to push into the array; for modifying, it is to find the element of the corresponding id, and then replace it; for deleting, it is to find the element of the corresponding id, and use the splice function to delete it; for the query, it is more complicated. The elements that meet the conditions have to be extracted and returned. Here only the id query is processed. If there are more, the code will be more complicated. Readers can try it by themselves.

Then modify src/components/Score.vue:

<template>
  <div>
    <template>
      <el-form ref="form" :inline="true" :model="queryForm" label-width="80px">
        <el-form-item label="id">
          <el-input v-model="queryForm.id"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSearch">查询</el-button>
        </el-form-item>
      </el-form>
      
      <el-button type="primary" @click="onAdd">新增</el-button>
      <el-table :data="tableData" style="width: 50%">
        <el-table-column prop="id" label="id" width="180"></el-table-column>
        <el-table-column prop="name" label="姓名" width="180"></el-table-column>
        <el-table-column prop="score" label="分数" width="180"></el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button @click="onUpdate(scope.row)" type="text" size="small">修改</el-button>
            <el-button @click="onDelete(scope.row)" type="text" size="small">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-dialog :title="title" :visible.sync="dialogVisible">
        <el-form ref="form" :model="form" label-width="80px">
          <el-form-item label="id">
            <el-input v-model="form.id"></el-input>
          </el-form-item>
          <el-form-item label="姓名">
            <el-input v-model="form.name"></el-input>
          </el-form-item>
          <el-form-item label="分数">
            <el-input v-model="form.score"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmit">确认</el-button>
            <el-button @click="onCancel">取消</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>
    </template>
  </div>
</template>

<script>
import { all, add, update, del, list } from '@/api/score.js'
require('../mock/mockscore.js');


export default {
  name: 'MyTable',
  data() {
    return {
      tableData: [],
      form: {
        id: null,
        name: '',
        score: null,
      },
      title: '',
      dialogVisible: false,
      queryForm: {
        
      }
    }
  },
  created(){
    all().then(res => {
      console.log(res)
      this.tableData = res.data
    })
  },
  methods: {
    onSearch(){
      list(this.queryForm).then(res => {
        this.tableData = res.data
      })
    },
    onAdd(){
      this.title = '新增'
      this.dialogVisible = true
    },
    onUpdate(row){
      this.title = '修改'
      this.dialogVisible = true
      this.form = row
    },
    onDelete(row){
      del(row.id).then(res =>{
        console.log(res)
        this.onSearch()
      })
    },
    onSubmit(){
      if(this.title == '新增'){
        add(this.form).then(res =>{
          console.log(res)
          this.dialogVisible = false
          this.onSearch()
        })
      }else if(this.title == '修改'){
        update(this.form).then(res => {
          console.log(res)
          this.dialogVisible = false
          this.onSearch()
        })
      }
    },
    onCancel(){
      this.dialogVisible = false
      this.resetForm()
    },
    resetForm(){
      this.form = {
        id: null,
        name: '',
        score: null
      }
    }
  }
}
</script>

<style scoped>
</style>

The code here is not the point. After all, it is more related to the processing logic of adding, deleting, checking and modifying the front-end interface. It has nothing to do with the mock itself and is only provided for readers' reference.

summary

The use of mock is not complicated, and it is quick to get started. It is generally used as a front-end test, and it will not be very complicated. I hope that readers can quickly get started with mock in the project through this article

 

おすすめ

転載: blog.csdn.net/sadoshi/article/details/122642076