在反应中使用提取时,MockServerWorker 不处理响应
MockServerWorker is not handling responses when using fetch in react
我在 React 课程中做测试驱动开发 -
我正在尝试针对 post 请求进行开发测试。以下是反应代码。
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;
单击按钮时 post 请求的测试是 -
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'
});
});
});
当测试为 运行 时,出现以下错误 -
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)
完整代码在githubhere。当我使用 axios.post
而不是 fetch 时,它工作正常。
我该如何解决这个错误 -
fetch
和rest.post
中的URL应该是相似的Docs。
在测试中指定确切的URL到rest.post
(类似于fetch
)。
rest.post("http://localhost:3000/api/1.0/users", (req, res, ctx) => {}
或者在组件内部指定路径fetch
(类似于rest.post
)。
fetch("/api/1.0/users", {})
我在 React 课程中做测试驱动开发 -
我正在尝试针对 post 请求进行开发测试。以下是反应代码。
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;
单击按钮时 post 请求的测试是 -
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'
});
});
});
当测试为 运行 时,出现以下错误 -
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)
完整代码在githubhere。当我使用 axios.post
而不是 fetch 时,它工作正常。
我该如何解决这个错误 -
fetch
和rest.post
中的URL应该是相似的Docs。
在测试中指定确切的URL到rest.post
(类似于fetch
)。
rest.post("http://localhost:3000/api/1.0/users", (req, res, ctx) => {}
或者在组件内部指定路径fetch
(类似于rest.post
)。
fetch("/api/1.0/users", {})