ctimmerm / axios-mock-adapter

Axios adapter that allows to easily mock requests
MIT License
3.44k stars 244 forks source link

Breaking change in v1.18.0 for onPost with FormData #253

Open cjmaynar opened 4 years ago

cjmaynar commented 4 years ago

Release of v1.18.0 causes tests using FormData with post requests to fail. It seems as of 1.18.0 onPost with an expected data of FormData returns a 404 instead of whatever the reply is supposed to be.

Below is a sample component and test that passes in v1.17.0 and fails in v1.18.0

import React from "react";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { shallow } from "enzyme";

let mock = new MockAdapter(axios);
const flushPromises = () => new Promise(resolve => setImmediate(resolve));

class Proof extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: ""
        };
    }

    componentDidMount() {
        const formData = new FormData();
        formData.append("confirm", true);
        axios.post("/foo/bar", formData)
            .then(response => {
                console.log(response);
                this.setState({message: "success"});
            })
            .catch(err => {
                console.log(err);
                this.setState({message: "error"});
            });
    }

    render() {
        return (
            <p>{this.state.message}</p>
        );
    }
}

describe("System Component", () => {

    it("test case", async () => {
        let wrapper = shallow(<Proof />);

        const formData = new FormData();
        formData.append("confirm", true);

        mock.onPost("/foo/bar", formData).replyOnce(200, {})
        await flushPromises();
        expect(wrapper.state().message).toEqual("success");
    })
});

After upgrading to v1.18.0 to make things pass the component must change to no longer send a FormData instance - to now be a regular JS object - and the test must change to expect that as well

AndrewsK30 commented 4 years ago

At nodejs/nestjs I had to add asymmetricMatch to de FormData mock

const formData = new FormData() as any;
formData.append('image', mockUploadFile);
formData.asymmetricMatch = (actual) => {
          // Validate and return true or false, 'this' is the expected
};
mock.onPut(url, formData).replyOnce(200);

because at utils.js at line 86 where the validation of the body happen

function isObjectMatching(actual, expected) {
  if (expected === undefined) return true;
  if (typeof expected.asymmetricMatch === "function") {
    return expected.asymmetricMatch(actual);
  }
  return isEqual(actual, expected);
}