我遇到一个问题,前端的模拟服务在测试期间无法始终加载正确的数据。这是问题的细分:
这种行为让我怀疑这是并发或计时问题——也许模拟服务在 Cypress 开始与其交互之前没有正确初始化。
需要注意的另一件事是,在我们使用 MSW 运行应用程序的同时,我们尝试在运行 Cypress UI 测试时使用相同的 MSW 实例。
对于上下文,这里有一个链接,介绍我们如何在 Cypress 中包含工人的使用:https://v1.mswjs.io/docs/api/setup-worker/use
有人遇到过类似的事情吗?或者您对调试或确保模拟数据加载一致有什么建议吗?
感谢您的帮助!
我将添加我的代码示例:
//test.cy.ts
describe('Example mock test case ', () => {
beforeEach(() => {
cy.visit('/?planNumber=123456');
// call the mock api
cy.mockTestMock();
});
it('Get a valid text from api', () => {
cy.get('#mockDataText').should(
'have.text',
'this text comes from api',
);
});
})
// mock-function.ts
Cypress.Commands.add('mockTestMock', () => {
cy.window().then((window) => {
const { worker, rest } = window.msw;
Cypress.log({
displayName: 'Example mock',
message: [],
});
worker.use(
rest.post(
`apiUrl`,
async (
req: RestRequest<any>,
res: ResponseComposition<any>,
ctx: RestContext,
) => {
return res(
ctx.delay(1000),
ctx.json({
text:"this text comes from api"
}),
);
},
),
);
});
Cypress.log({
displayName: 'Did cy.intercept',
message: [],
});
});
import './commands';
declare global {
interface Window {
msw: any;
}
namespace Cypress {
interface Chainable {
mockTestMock(): void;
}
}
}
这个问题可能是无法克服的,因为你直接从
cy.visit()
进入模拟步骤。
describe('Example mock test case ', () => {
beforeEach(() => {
cy.visit('/?planNumber=123456');
// call the mock api
cy.mockTestMock();
});
您尚未显示应用程序序列的详细信息,但必须假设打开应用程序会设置真正的 Service Worker,然后调用 api。您的模拟必须在两个步骤之间注入才能始终有效。
您可以尝试在访问命令的
onBeforeLoad
或 onLoad
挂钩中执行 msw 步骤,
describe('Example mock test case ', () => {
beforeEach(() => {
cy.visit('/?planNumber=123456', {
'onLoad': (contentWindow) => {
const { worker, rest } = contentWindow.msw;
//etc
}
});
});
但竞争条件似乎仍将保留。
另一种策略是在测试期间完全删除 Service Worker,只使用
cy.intercept()
来模拟您的 API 调用,例如
describe('Example mock test case ', () => {
beforeEach(() => {
Cypress.on('window:before:load', (win) => {
// @ts-ignore
delete win.navigator.__proto__.serviceWorker
})
cy.intercept('apiUrl', {text:"this text comes from api"})
cy.visit('/?planNumber=123456');
});