I’m doing test driven development in react course –
I’m trying to development test for post request. Below is by react code.
import React from "react"; import axios from "axios"; class SignUpPage extends React.Component { state = { } onChange = (event) => { const {id, value} = event.target; this.setState({ [id]:value }) }; onChangeUsername = (event) => { const currentValue = event.target.value; this.setState({ username: currentValue, // disabled: currentValue !== this.state.confirmPassword }); }; onChangeEmail = (event) => { const currentValue = event.target.value; this.setState({ email: currentValue, // disabled: currentValue !== this.state.confirmPassword }); }; onChangePassword= (event) => { const currentValue = event.target.value; this.setState({ password: currentValue, // disabled: currentValue !== this.state.confirmPassword }); }; onChangeConfirmPassword= (event) => { const currentValue = event.target.value; this.setState({ confirmPassword: currentValue, // disabled: currentValue !== this.state.password }); }; submit = (event) => { event.preventDefault(); const {username, email, password } = this.state; const body = { username, email, password } //axios.post('/api/1.0/users', body); fetch("/api/1.0/users", { method: 'POST', headers : { "Content-Type": "application/json" }, body: JSON.stringify(body) }); }; render() { let disabled = true; const { password, confirmPassword} = this.state; if(password && confirmPassword) { disabled = password !== confirmPassword; } // setTimeout(() => { // this.setState({disabled: false}); // console.log('updating disabled'); // }, 1000); return ( <div className="col-lg-6 offset-lg-3 col-md-8 offset-md-2"> <form className="card mt-5"> <h1 className="text-center card-header">Sign Up</h1> <div className="card-body"> <div className="mb-3"> <label htmlFor="username" className="form-label">Username</label> <input id="username"onChange={this.onChange} className="form-control"/> </div> <div className="mb-3"><label htmlFor="email" className="form-label">E-mail</label> <input id="email" onChange={this.onChange} className="form-control mb-4"/> </div> <div className="mb-3"><label htmlFor="password" className="form-label">Password</label> <input id="password" type="password" onChange={this.onChange} className="form-control"/> </div> <div className="mb-3"><label htmlFor="confirmPassword" className="form-label">Confirm Password</label> <input id="confirmPassword" type="password" onChange={this.onChange} className="form-control"/> </div> <div className="text-right"> <button disabled={disabled} onClick={this.submit} className="btn btn-primary">Sign Up</button> </div> </div> </form> </div> ); } } export default SignUpPage;
and the test for the post request when the button is clicked is –
import SignUpPage from "./SignUpPage"; import {render, screen} from "@testing-library/react"; import userEvent from "@testing-library/user-event"; const axios = require('axios').default; import { setupServer} from "msw/node"; import { rest } from "msw"; describe("Interactions", () => { it("sends username, email and password to backend after clicking the button", async () => { let reqBody; const server = setupServer( rest.post("/api/1.0/users", (req, res, ctx) => { console.log("the message is"); reqBody = req.body; return res(ctx.status(200)); }) ); server.listen(); render(<SignUpPage/>); const usernameInput = screen.getByLabelText('Username'); const emailInput = screen.getByLabelText('E-mail'); const passwordInput = screen.getByLabelText('Password'); const confirmPassword = screen.getByLabelText('Confirm Password'); userEvent.type(usernameInput, 'user1'); userEvent.type(emailInput, 'user1@mail.com'); userEvent.type(passwordInput, 'P4ssw0rd'); userEvent.type(confirmPassword, 'P4ssw0rd'); const button = screen.queryByRole('button', {name: 'Sign Up'}); expect(button).toBeEnabled(); userEvent.click(button); await new Promise(resolve => setTimeout(resolve, 1500)); // const firstCallofMockFunction = mockFn.mock.calls[0]; //const body = JSON.parse(firstCallofMockFunction[1].body); expect(reqBody).toEqual({ username: 'user1', email: 'user1@mail.com', password: 'P4ssw0rd' }); }); });
When the test is run I get below error –
console.warn [MSW] Warning: captured a request without a matching request handler:
• POST http://localhost:3000/api/1.0/users
If you still wish to intercept this unhandled request, please create a request handler for it. Read more: https://mswjs.io/docs/getting-started/mocks
console.error Error: Error: connect ECONNREFUSED ::1:3000 at Object.dispatchError (/home/rajkumar/Coding/react/react-tdd/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:63:19) at Request. (/home/rajkumar/Coding/react/react-tdd/node_modules/jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js:655:18) at Request.emit (node:events:539:35) at NodeClientRequest. (/home/rajkumar/Coding/react/react-tdd/node_modules/jsdom/lib/jsdom/living/helpers/http-request.js:121:14) at NodeClientRequest.emit (node:events:539:35) at NodeClientRequest.Object..NodeClientRequest.emit (/home/rajkumar/Coding/react/react-tdd/node_modules/@mswjs/interceptors/src/interceptors/ClientRequest/NodeClientRequest.ts:284:22) at Socket.socketErrorListener (node:_http_client:454:9) at Socket.emit (node:events:527:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) undefined
● Interactions › sends username, email and password to backend after clicking the button expect(received).toEqual(expected) // deep equality Expected: {"email": "user1@mail.com", "password": "P4ssw0rd", "username": "user1"} Received: undefined 94 | await new Promise(resolve => setTimeout(resolve, 1500)); 95 | > 96 | expect(reqBody).toEqual({ | ^ 97 | username: 'user1', 98 | email: 'user1@mail.com', 99 | password: 'P4ssw0rd' at Object.<anonymous> (src/pages/SignUpPage.spec.js:96:25)
The complete code is on github here. When I use axios.post
instead of fetch it is working fine.
How can I fix this error –
Advertisement
Answer
The URL in fetch
and rest.post
should be similar Docs.
Either specify the exact URL to rest.post
(similar to fetch
) in the test.
rest.post("http://localhost:3000/api/1.0/users", (req, res, ctx) => {}
Or specify a path to fetch
(similar to rest.post
) inside the component.
fetch("/api/1.0/users", {})