使用axios-mock-adapter對axios請求進行mock


在使用jest和enzyme對react進行單元測試時,如果我們需要對axios的請求進行測試,可以使用axios-mock-adapter。

這里只是拿單元測試舉例,正常邏輯里的mock也可以使用,但是既然單元測試都通過了正常邏輯里不用也無所謂了(因為正常邏輯里加了后面也得刪...)。

vSwitch.ui.jsx代碼如下:(看黃色部分即可)

import React, { useState, useEffect } from "react";
import axios from '../../../request';
import { Form, Input, Select } from 'antd';
import { FetchAvailabilityZoneURL } from "../url";

const { Option } = Select;
const TextArea = Input.TextArea;

const ReactRender = (props) => {
    const { type, cellId, db } = props;
    const { getFieldDecorator } = props.form;
    const doc = db.getDoc(type, cellId);
    const vpcDoc = db.getDocByRefId(doc.vpc_id);
    let vpcName = vpcDoc.name;
    const onSubmit = (e) => {
        e.preventDefault();
        props.form.validateFields((err, values) => {
            if (!err) {
                // 所屬vPC始終要用vpc_id的值保存
                values.vpc_id = doc.vpc_id;
                db.updateDoc(type, cellId, values);
            }
        });
    };

    let [allData, setData] = useState(() => {
        return { availabilityZoneData: [] };
    });

 useEffect(() => { axios.post(FetchAvailabilityZoneURL, { "multi": true }) .then((response) => { const availabilityZoneData = response.data.ids; setData(allData => ({ ...allData, availabilityZoneData })); }).catch((error) => { }); }, []);     return (
        <Form onChange={onSubmit} onClick={onSubmit}>
            <Form.Item label="名稱">
                {getFieldDecorator('name', {
                    initialValue: doc.name,
                    rules: [{ required: true, message: '請填寫名稱' }],
                })(<Input />)}
            </Form.Item>
            <Form.Item label="描述">
                {getFieldDecorator('description', {
                    initialValue: doc.description
                })(<TextArea rows={5} />)}
            </Form.Item>
            <Form.Item label="所屬vPC">
                <React.Fragment>
                    {getFieldDecorator('vpc_id', {
                        initialValue: vpcName,
                        rules: [{ required: true, message: '自動關聯vPC' }],
                    })(<Input hidden />)}
                    <span>{vpcName}</span>
                </React.Fragment>
            </Form.Item>
            <Form.Item label="IPv4地址范圍">
                {getFieldDecorator('cidr_block', {
                    initialValue: doc.cidr_block,
                    rules: [{
                        required: true, message: '請填寫IPv4地址范圍'
                    }, {
                        pattern: /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/,
                        message: '請填寫正確的CIDR(如:192.168.11.0/16)'
                    }],
                })(<Input />)}
            </Form.Item>
            <Form.Item label="可用區">
                {getFieldDecorator('availability_zone', {
                    initialValue: doc.availability_zone || undefined,
                    rules: [{ required: true, message: '請選擇可用區' }],
                })(
                    <Select
                        showSearch
                        style={{ width: '100%' }}
                        placeholder="請選擇可用區"
                        optionFilterProp="children"
                        filterOption={(input, option) =>
                            option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                        }
                    >
                        {
                            allData.availabilityZoneData && allData.availabilityZoneData.map(item =>
                                <Option key={item} value={item}>{item}</Option>
                            )
                        }
                    </Select>
                )}
            </Form.Item>
        </Form>
    )
};

export default Form.create()(ReactRender);

 

vSwitch.test.jsx代碼如下:(看黃色部分即可)

import MockAdapter from "axios-mock-adapter";
import axios from "../../../request";
import VSwitch from "../component/vSwitch";
import { mount } from 'enzyme';
import { FetchAvailabilityZoneURL } from "../url";
import { getDatabase, getGlobalID } from "../../../database";

describe("vSwitch測試", () => {
    const mock = new MockAdapter(axios);
    const vSwitch = new VSwitch();
    const db = getDatabase();
    // 模仿UI操作,添加一個cell,然后立即調用渲染方法
    vSwitch.onAdd("alicloud_vswitch", { id: 1 });
    const wrapper = mount(vSwitch.render("alicloud_vswitch", 1));
    // 為select下拉框設置默認值
    // const component = wrapper.dive();
    wrapper.instance().setFieldsValue({
        availability_zone: `cn-shanghai-a`,
    });

    it('render', () => {
        const data = { ids: ["cn-shanghai-a", "cn-shanghai-b", "cn-shanghai-c", "cn-shanghai-d", "cn-shanghai-e", "cn-shanghai-f"] };
        mock.onPost(FetchAvailabilityZoneURL).reply( (config) => { return new Promise(function (resolve, reject) { resolve([200, data]); }).then(() => { wrapper.find('#availability_zone .ant-select-selection__rendered').simulate('click'); expect(wrapper.find('.ant-select-dropdown-menu li').length).toBe(6); }); } );

        expect(wrapper.find("FormItem").length).toBe(5);
        expect(wrapper.find("FormItem").first().props().label).toBe('名稱');
        expect(wrapper.find("FormItem").get(1).props.label).toBe('描述');
        expect(wrapper.find("FormItem").get(2).props.label).toBe('所屬vPC');
        expect(wrapper.find("FormItem").get(3).props.label).toBe('IPv4地址范圍');
        expect(wrapper.find("FormItem").last().props().label).toBe('可用區');
    });

    it('onInParent', () => {
        const vpcCellId = 10;
        const vpcDoc = db.saveDoc("alicloud_vpc", vpcCellId, {
            name: "test",
            cidr_block: "10.10.0.0/16",
            description: "test"
        });
        // 和vPC建立關系
        const vpcCell = { data: { type: "alicloud_vpc", provider: "alicloud" }, id: vpcCellId };
        vSwitch.onInParent("alicloud_vswitch", { id: 1 }, vpcCell);
        const vswtichDoc = db.getDoc("alicloud_vswitch", 1);
        expect(vswtichDoc.vpc_id).toBe(getGlobalID(vpcDoc));
    });

    it('onInputChange', () => {
        wrapper.find('input').at(0).simulate('change', { target: { value: "test_vswitch_name" } });
        expect(wrapper.find('input').at(0).prop('value')).toBe('test_vswitch_name');
        wrapper.find('input').at(1).simulate('change', { target: { value: "test_vpc_description" } });
        expect(wrapper.find('input').at(1).prop('value')).toBe('test_vpc_description');
        wrapper.find('input').at(3).simulate('change', { target: { value: "192.168.11.0/16" } });
        expect(wrapper.find('input').at(3).prop('value')).toBe('192.168.11.0/16');
        wrapper.find('#availability_zone .ant-select-selection__rendered').simulate('click');
        wrapper.find('.ant-select-dropdown-menu li').at(0).simulate('click');
        expect(wrapper.find('.ant-select-selection-selected-value').prop('title')).toBe('cn-shanghai-a');
    });

    it('onDelete', () => {
        // 刪除alicloud_vswitch
        vSwitch.onDelete("alicloud_vswitch", { id: 1 });
        const vswtichDoc = db.getDoc("alicloud_vswitch", 1);
        expect(vswtichDoc).toBeUndefined();
    });
});

 

總的來說就是要在Promise的回調里測試才是有效的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM