模拟 Service Worker returns 空
Mock Service Worker returns empty
我是 React 测试库 的新手。我正在尝试测试一个调用一些 apis 的简单组件
然后它用这些 api 的数据填充输入。但是当我 运行 npm test
它一直向我显示:收到的值为空
预期元素具有值:
100
收到:
7 | it('displays returned client info on successful fetch', async () => {
8 | render(<Client />);
> 9 | expect(await screen.findByLabelText('IFU')).toHaveValue('100');
| ^
10 | });
11 |
12 | it('displays error message when fetching tasks raises error', async () => {
at Object.<anonymous> (src/unit-tests/Client.test.js:9:51)
这是我的测试
import { render, screen } from '@testing-library/react';
import Client from './../components/Client';
import { mswServer } from './api-mocks/msw-server';
import { clientHandlerException } from './api-mocks/handlers';
describe('Component: Client', () => {
it('displays returned client info on successful fetch', async () => {
render(<Client />);
expect(await screen.findByLabelText('IFU')).toHaveValue('100');
});
it('displays error message when fetching tasks raises error', async () => {
mswServer.use(clientHandlerException);
render(<Client />);
});
});
handlers.js
import { rest } from 'msw';
const importateur = {numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris"}
export const clientHandler = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) => {
// res(ctx.json(mockClientInfo))
return res(
ctx.status(200),
ctx.json(importateur)
)
});
export const clientHandlerException = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) =>
res(ctx.status(500), ctx.json({ message: 'Deliberately broken request' }))
);
export const handlers = [clientHandler];
msw-server.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const mswServer = setupServer(...handlers);
setupTests.js
import '@testing-library/jest-dom';
import { mswServer } from './msw-server';
beforeAll(() => mswServer.listen());
afterEach(() => mswServer.resetHandlers());
afterAll(() => mswServer.close());
我的组件
export interface IClient {
numeroRc: string,
description: string,
ifu: string,
ice: string
}
const Client = (props: ClientProps) => {
const [clientData, setClientData] = React.useState<IClient>(
{numeroRc: "",
description: "",
ifu: "",
ice: ""}
);
//other useEffect s that call other apis
React.useEffect(() => {
(async () => {
const response = await getClientInfo();
setClientData(response as IClient);
})();
}, [])
return(
<Stack direction="row" spacing={3} className='client' >
<TextField id="numro-rc" label="Numero RC" variant="outlined" value={clientData.numeroRc}/>
<TextField id="client" label="Client" variant="outlined" value={clientData.description}/>
<TextField id="ifu" label="IFU" variant="outlined" value={clientData.ifu} />
<TextField title='ice' id="ice" label="ICE" variant="outlined" value={clientData.ice} />
</Stack>
);
}
更新
getClientInfo 是一种使用 axios 调用我的 api 的方法(我将所有 apis 调用放在文件 api.tsx 中)
axios.defaults.baseURL = 'http://localhost:8080/api'
...
export const getClientInfo = async () => {
try {
const response = await axios.get(`/informationsClient`);
return response.data;
} catch(e) {
console.log(e);
return 0;
}
}
请问这可能是什么问题?
问题是您不是在等待值,而是在等待元素,并且当组件以 ""
的值安装时元素就在那里,因此您的断言失败。
因此,您需要 await
作为值,您可以使用 waitFor
作为相同的值。
import { render, screen, waitFor } from "@testing-library/react";
describe("Component: Client", () => {
it("displays returned client info on successful fetch", async () => {
render(<Client />);
const element = screen.getByLabelText("IFU");
await waitFor(() => {
expect(element).toHaveValue("100");
});
});
});
您也可以使用 findByDisplayValue
:
import { render, screen, waitFor } from "@testing-library/react";
describe("Component: Client", () => {
it("displays returned client info on successful fetch", async () => {
render(<Client />);
const element = await screen.findByDisplayValue("100");
expect(element).toBeInTheDocument();
});
});
更新:
完成以下两项更改后,上述两种测试方法都可以正常工作。
您在 api-mocks
中创建了一个 setupTests.ts
文件,该文件 没有 效果,因为 CRA 不考虑 任何 setupTest.ts
文件,但只有 src
里面的文件。您会注意到 src
中已经有一个 setupTest.ts
文件,只需将所有设置代码移至此文件即可。
模拟服务器 return 是一个数组,但您的 clientData
状态需要一个对象,因此请执行以下任一操作:
将模拟服务器更新为 return 对象而不是数组(在 handlers.js
中)
js const client = { numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris" };
或者在设置状态之前从数组中提取对象(在Client.tsx
)。
const response = await getClientInfo();
setClientData(response[0]);
您还需要为所有输入提供一个 onChange
处理程序以消除警告。
我是 React 测试库 的新手。我正在尝试测试一个调用一些 apis 的简单组件
然后它用这些 api 的数据填充输入。但是当我 运行 npm test
它一直向我显示:收到的值为空
预期元素具有值: 100 收到:
7 | it('displays returned client info on successful fetch', async () => {
8 | render(<Client />);
> 9 | expect(await screen.findByLabelText('IFU')).toHaveValue('100');
| ^
10 | });
11 |
12 | it('displays error message when fetching tasks raises error', async () => {
at Object.<anonymous> (src/unit-tests/Client.test.js:9:51)
这是我的测试
import { render, screen } from '@testing-library/react';
import Client from './../components/Client';
import { mswServer } from './api-mocks/msw-server';
import { clientHandlerException } from './api-mocks/handlers';
describe('Component: Client', () => {
it('displays returned client info on successful fetch', async () => {
render(<Client />);
expect(await screen.findByLabelText('IFU')).toHaveValue('100');
});
it('displays error message when fetching tasks raises error', async () => {
mswServer.use(clientHandlerException);
render(<Client />);
});
});
handlers.js
import { rest } from 'msw';
const importateur = {numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris"}
export const clientHandler = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) => {
// res(ctx.json(mockClientInfo))
return res(
ctx.status(200),
ctx.json(importateur)
)
});
export const clientHandlerException = rest.get("http://localhost:8080/api/informationsClient", async (req, res, ctx) =>
res(ctx.status(500), ctx.json({ message: 'Deliberately broken request' }))
);
export const handlers = [clientHandler];
msw-server.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const mswServer = setupServer(...handlers);
setupTests.js
import '@testing-library/jest-dom';
import { mswServer } from './msw-server';
beforeAll(() => mswServer.listen());
afterEach(() => mswServer.resetHandlers());
afterAll(() => mswServer.close());
我的组件
export interface IClient {
numeroRc: string,
description: string,
ifu: string,
ice: string
}
const Client = (props: ClientProps) => {
const [clientData, setClientData] = React.useState<IClient>(
{numeroRc: "",
description: "",
ifu: "",
ice: ""}
);
//other useEffect s that call other apis
React.useEffect(() => {
(async () => {
const response = await getClientInfo();
setClientData(response as IClient);
})();
}, [])
return(
<Stack direction="row" spacing={3} className='client' >
<TextField id="numro-rc" label="Numero RC" variant="outlined" value={clientData.numeroRc}/>
<TextField id="client" label="Client" variant="outlined" value={clientData.description}/>
<TextField id="ifu" label="IFU" variant="outlined" value={clientData.ifu} />
<TextField title='ice' id="ice" label="ICE" variant="outlined" value={clientData.ice} />
</Stack>
);
}
更新
getClientInfo 是一种使用 axios 调用我的 api 的方法(我将所有 apis 调用放在文件 api.tsx 中)
axios.defaults.baseURL = 'http://localhost:8080/api'
...
export const getClientInfo = async () => {
try {
const response = await axios.get(`/informationsClient`);
return response.data;
} catch(e) {
console.log(e);
return 0;
}
}
请问这可能是什么问题?
问题是您不是在等待值,而是在等待元素,并且当组件以 ""
的值安装时元素就在那里,因此您的断言失败。
因此,您需要 await
作为值,您可以使用 waitFor
作为相同的值。
import { render, screen, waitFor } from "@testing-library/react";
describe("Component: Client", () => {
it("displays returned client info on successful fetch", async () => {
render(<Client />);
const element = screen.getByLabelText("IFU");
await waitFor(() => {
expect(element).toHaveValue("100");
});
});
});
您也可以使用 findByDisplayValue
:
import { render, screen, waitFor } from "@testing-library/react";
describe("Component: Client", () => {
it("displays returned client info on successful fetch", async () => {
render(<Client />);
const element = await screen.findByDisplayValue("100");
expect(element).toBeInTheDocument();
});
});
更新:
完成以下两项更改后,上述两种测试方法都可以正常工作。
您在
api-mocks
中创建了一个setupTests.ts
文件,该文件 没有 效果,因为 CRA 不考虑 任何setupTest.ts
文件,但只有src
里面的文件。您会注意到src
中已经有一个setupTest.ts
文件,只需将所有设置代码移至此文件即可。模拟服务器 return 是一个数组,但您的
clientData
状态需要一个对象,因此请执行以下任一操作:将模拟服务器更新为 return 对象而不是数组(在
handlers.js
中)js const client = { numeroRc: "1000", description: "desc one", ifu: "100", ice: "789", company: "mycom", city: "paris" };
或者在设置状态之前从数组中提取对象(在
Client.tsx
)。const response = await getClientInfo(); setClientData(response[0]);
您还需要为所有输入提供一个 onChange
处理程序以消除警告。