Mah*_*dra 5 mocking typescript reactjs next.js msw
我正在集成一个模拟 API,它基本上发送一个响应对象,其中包含一组应该显示在 UI(聊天框)中的消息以及用户名、用户图片等。
由于重大更改,我在设置msw 1.1.0with Next JS 13.2.1 (带有布局的实验应用程序目录)时遇到了一些麻烦。然而这是我的代码。
到目前为止我的代码是这样设置的
src/app/(用户)/live-view/page.tsx
import React from "react";
import ThreadPostList from "../../components/threadList";
import { worker } from '../../../mocks/browser';
if (process.env.NODE_ENV === 'development') {
worker.start();
}
async function getMessages() {
const response = await fetch("http://localhost:3000/api/messages");
// const data = await response.json();
return response;
}
async function LiveViewPage() {
const messages = await getMessages();
const convertedMessages = Object.keys(messages);
// console.log(convertedMessages, "ConvertedMessages");
Object.values(messages).forEach(val => console.log(val));
return (
<div className="border-t border-gray-200 py-4 divide-y divede-gray-200">
<ThreadPostList />
</div>
);
}
export default LiveViewPage;
Run Code Online (Sandbox Code Playgroud)
我的 Msw 模拟 API 位于
src/mocks/handler.ts
import { rest } from "msw";
import { UserWithMessages } from "./types";
const mockData: UserWithMessages[] = [
{
user: {
id: "user1",
name: "John Doe",
profilePic: "https://example.com/user1.jpg",
},
messages: [
{
id: "msg1",
senderId: "user1",
text: "Hey, how are you?",
createdAt: new Date("2022-01-01T12:00:00Z"),
},
{
id: "msg2",
senderId: "user1",
text: "Did you get my email?",
createdAt: new Date("2022-01-02T12:00:00Z"),
},
],
},
{
user: {
id: "admin",
name: "Admin",
profilePic: "https://example.com/admin.jpg",
},
messages: [],
},
];
export const handlers = [
rest.get<UserWithMessages[]>("/api/messages", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(mockData));
}),
];
Run Code Online (Sandbox Code Playgroud)
最后我的 browser.ts 位于
src/mocks/browser.ts
"use client"
import { setupWorker } from 'msw';
import { handlers } from './handlers';
export const worker = setupWorker(...handlers);
Run Code Online (Sandbox Code Playgroud)
当我运行服务器时它抛出错误
错误:无法访问服务器上的worker.start。您不能从服务器组件点入客户端模块。您只能传递导入的名称。
我在哪里以及如何启动我的工作人员?我是否必须在模拟下创建一个文件并在那里调用服务器并在我的 page.tsx 中导入该组件?任何帮助将不胜感激,谢谢
自从 Mock Service Worker 进入稳定版本以来,我一直在努力让 Mock Service Worker 在应用程序目录结构中与 NextJS 一致运行。我已经取得了一定程度的成功,但我怀疑这不是理想的解决方案。我们仍在等待 NextJS 团队的合法示例实现。
由于您看到的确切错误,我们无法调用服务器渲染组件上的工作程序。相反,我已将 fetch 调用转移到一个共享服务中,该服务只是打字稿:
./services/api-service.ts
async function initMocks() {
if (typeof window === 'undefined') {
const { server } = await import('./src/mocks/server')
await server.listen({ onUnhandledRequest: 'bypass' })
} else {
const { worker } = await import('./src/mocks/browser')
await worker.start({ onUnhandledRequest: 'bypass' })
}
}
// Note the change in ENV var name here
// https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
if (process.env.NEXT_PUBLIC_MOCK_APIS === 'enabled') {
initMocks()
}
export const makeApiRequest = async (path: string) => {
try {
const resp = await fetch(path)
if (resp.ok) {
const result = await resp.json()
return result
}
} catch (err: any) {
// handle errors
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道为什么,但是在像这样的较低级别实现 MSW,并且在实际的 React 组件之外对我来说比尝试在页面或布局级别初始化它更成功,因为它是在 NextJS 页面目录中实现的例子。
这会将您的页面组件更改为顶部看起来更像这样:
src/app/(用户)/live-view/page.tsx
import React from "react";
import ThreadPostList from "../../components/threadList";
import { makeApiRequest} from './services/api-service';
async function getMessages() {
const response = await makeApiRequest("http://localhost:3000/api/messages");
return response;
}
Run Code Online (Sandbox Code Playgroud)
我在这里注意到的另一件事是,您的处理程序正在捕获相对路径,这也可能在服务器端出错。服务器处理程序缺少根 URL 的上下文,并且我通过其中的完整路径或路径匹配取得了更好的成功。所以要么:
export const handlers = [
rest.get<UserWithMessages[]>("http://localhost:3000/api/messages", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(mockData));
}),
];
Run Code Online (Sandbox Code Playgroud)
或者:
export const handlers = [
rest.get<UserWithMessages[]>("*/api/messages", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(mockData));
}),
];
Run Code Online (Sandbox Code Playgroud)
如果您想使用 MSW 运行 Jest 测试或在已部署环境或计算机以外的其他地方运行某些测试,后者可能会派上用场。
从技术上讲,在您的问题以及任何遵循 NextJS 文档中概述的最佳实践的应用程序中,我们根本不需要 MSW 的浏览器实现,因为所有数据都将在服务器组件中获取并用于补充客户端。但是,我将其留在这里是为了与以前的实现进行比较时提供一些一致性。
在我写这篇文章时,我正在使用 msw@1.2.1 和 next@13.4.3
| 归档时间: |
|
| 查看次数: |
3564 次 |
| 最近记录: |