我坚持使用赛普拉斯的灯具。无法通过SSR和导航路由拦截XHR请求。
cypress / integration / page.js:
const fetch = require("unfetch")
describe("/about", () => {
beforeEach(() => {
cy.visit("/", { // Visit home page to trigger SSR
onBeforeLoad (win) {
win.fetch = fetch // replace fetch with xhr implementation
},
})
})
it("Has a correct title", () => {
cy.server()
cy.fixture("about").then(about => {
// about object is correct here, like {title: "About+"}
cy.route("GET", "http://localhost:8080/api/documents/url", about) // Not sure where .route should be
cy.get(".main > :nth-child(1) > a").click() // Navigate to the /about page
cy.route("GET", "http://localhost:8080/api/documents/url", about) // Tried both ways
// This hits my server API without stubbing, getting {title: "About"}
cy.title().should("eq", "About+") // About != About+
})
})
})
cypress / fixtures / about.json:
{"title": "About+"}
我在开发工具中看到一个XHR请求(类型= xhr),它不使用上面的about
存根对象,而是命中了真正的API。为什么?再次检查URL和方法-100%相同。可以将route
耦合到visit
并忽略基于点击的路由吗?!
答案 0 :(得分:0)
再次检查一下,我找到了解决方案。让我向感兴趣的所有人分享详细信息:
1)我使用了 Next.js ,它是用于SSR的出色工具,但是它不允许您根据this禁用服务器端渲染(尚未),并且this个问题。
2)您可以将赛普拉斯与SSR页面一起使用,但是通过这种方式,您只能测试真实的HTML。这意味着您必须将测试与真实数据耦合(在大多数情况下效果不佳),或者对数据库本身进行存根处理(速度较慢)。通常,您想存根HTTP请求。
3)赛普拉斯无法处理fetch
请求,并且使用基于XHR的实现对fetch
进行模拟比我想象的要难。
首先,您需要:
// cypress/integration/your-test.js
Cypress.on('window:before:load', (win) => {
delete win.fetch
})
然后:
// pages/your-page.js
Entry.getInitialProps = async function() {
window.fetch = require("unfetch").default
...
}
我尝试的其他删除和更新代码行组合未产生积极的结果。例如,当我在测试文件中有window.fetch =
行时,它行不通,而fetch.toString()
给出了"native code"
。不知道为什么,没有时间进一步探索。
Axios解决了上述问题,但我不喜欢用多余的东西肿我的捆绑包。您只能注入基于XHR的fetch
进行测试。
4)最重要的缺失部分。您需要等待路线。
it("Has a correct title", () => {
cy.visit("/")
cy.server()
cy.route("GET", "http://localhost:8080/api/documents/url/about", {title: "About+"}).as("about")
cy.get("[href='/about']").click()
cy.wait("@about") // !!!
cy.get("h1").contains("About+")
})