Mat*_*mas 2 server-side-rendering next.js cypress
我正在尝试找到一种方法来模拟Next.js's getInitialProps。
我目前正在使用 cypress 运行 E2E 测试,但无法找到一种方法来模拟服务器端获取,而不需要启动模拟服务器来进行获取。我很好奇是否有人找到了更好的方法?
谢谢你!
Suc*_*UKR 14
从 NextJs 文档的此页面开始:NextJs - getInitialProps
很高兴知道:
getInitialProps是一个遗留 API。我们建议使用getStaticPropsorgetServerSideProps代替。
我决定仅使用getServerSideProps- 希望这能转化为您特定的 SSR 方法。
之前的例子
Gleb Bahmutov 在Mock Network When using Next.js getServerSideProps Call上有一篇关于此问题的博客,但它是 Cypress v9 项目,并且存储库尚未更新到 Cypress 10+(这不是一个好兆头)。
无论如何,我尝试在 Cypress 12.17.0 中运行此存储库,但 NextJs 服务器不断重新启动 Cypress GUI(反之亦然),因此我猜测有关不在 Cypress 节点进程内启动服务器的警告是有效的。
使用 NextJs 自定义服务器
自定义 Next.js 服务器允许您 100% 以编程方式启动服务器,以便使用自定义服务器模式。
实际上我在GeeksForGeeks上使用过这个,但我认为你使用哪一个并不重要。
以 Gleb 的应用程序和规范为起点,我向global.fetch()应用程序getServerSideProps调用中使用的方法添加了一个简单的补丁。
步骤是
mocks.json使用您想要测试的模拟数据创建一个文件localhost:3000检查应用程序是否已启动cypress open并运行规范/服务器/服务器.js
/node ./server/server.js使用或添加脚本在终端中运行package.json。
const next = require('next')
const http = require('http')
const mocks = require('./mocks.json')
const app = next({dev: process.env.NODE_ENV !== 'production'})
/* Cypress mocking for getServerSideProps */
const originalFetch = global.fetch
global.fetch = (url) => {
const mock = mocks[url]
if (mock) {
return new Response(JSON.stringify(mock.body), {status: mock.status})
} else {
return originalFetch(url)
}
}
/* "standard" NextJs custom server */
app.prepare().then(() => {
const server = http.createServer((req, res) => {
console.log('req.url', req.url)
// Handle API routes
if (req.url.startsWith('/api')) {
// Your API handling logic here
} else {
// Handle Next.js routes
return app.getRequestHandler()(req, res)
}
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
Run Code Online (Sandbox Code Playgroud)
/服务器/mocks.json
{
"https://icanhazdadjoke.com/": { // exact match to URL called in the app
"statusCode": 200,
"body": {
"id": "NmbFtH69hFd",
"joke": "Our wedding was so beautiful, even the cake was in tiers",
"status": 200
}
}
}
Run Code Online (Sandbox Code Playgroud)
/cypress/e2e/spec.cy.js
const mocks = require('../../server/mocks.json')
it('getServerSideProps returns mock', () => {
cy.visit('http://localhost:3000')
cy.get('[data-cy="joke"]')
.should('have.text', mocks['https://icanhazdadjoke.com/'].body.joke)
})
Run Code Online (Sandbox Code Playgroud)
结果
删除实现模拟的 server.js 块
局限性
您无法在 Cypress 测试中即时设置模拟数据,因为服务器在测试开始之前就已经运行。
可以通过cy.exec()启动和停止服务器来实现此目的,但我没有尝试过。
如果可以重新启动服务器,则mocks.json可以从测试内部进行更改,但我很高兴在静态文件中设置模拟,因为它降低了复杂性。
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |