axios-mock-adapter
axios-mock-adapter copied to clipboard
Breaking change in v1.18.0 for onPost with FormData
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
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);
}