代码之家  ›  专栏  ›  技术社区  ›  jamesdlivesinatree

组件测试建议下一个13.4+与应用程序目录

  •  0
  • jamesdlivesinatree  · 技术社区  · 2 年前

    我在想办法嘲笑 Next.js getInitialProps

    我目前正在使用柏树来运行E2E测试,并且找不到一种方法来模拟服务器端获取,而不为获取旋转一个模拟服务器。我很好奇是否有人找到了更好的方法?

    非常感谢。

    0 回复  |  直到 5 年前
        1
  •  10
  •   SuchAnIgnorantThingToDo-UKR    2 年前

    从NextJs文档的这一页开始: NextJs - getInitialProps

    很高兴知道: getInitialProps 传统API 。我们建议使用 getStaticProps getServerSideProps 相反

    我决定与合作 getServerSideProps 只是-希望这将转化为您特定的SSR方法。


    前面的例子

    Gleb Bahmutov在这里有一个关于这方面的博客 Mock Network When Using Next.js getServerSideProps Call 但它是Cypress v9项目,回购尚未更新到Cypress 10+(这不是好兆头)。

    无论如何,我尝试在Cypress 12.17.0中运行这个repo,但NextJs服务器一直在重新启动Cypress GUI(反之亦然),所以我想关于没有在Cypresss节点进程内启动服务器的警告是有效的。


    使用NextJs自定义服务器

    参考编号: NextJs Custom Server

    自定义Next.js服务器允许您以100%编程方式启动服务器,以便使用 自定义服务器模式

    实际上我用的是 GeeksForGeeks ,但我认为你用哪一个并不重要。

    以Gleb的应用程序和规范为起点,我在 global.fetch() 应用程序中使用的方法 getServerSideProps 呼叫

    步骤是

    • 创建 mocks.json 包含要测试的模拟数据的文件
    • 启动自定义服务器
    • 导航到 localhost:3000 检查该应用程序是否已启动
    • 开始 cypress open 并运行规范

    /server/server.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')
     })
    })
    

    /server/mmocks.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
        }
      }
    }
    

    /柏树/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)
    })
    

    后果

    enter image description here

    删除实现mocking的server.js块

    enter image description here

    局限性

    您不能在Cypress测试中动态设置mock数据,因为服务器在测试开始之前就已经运行了。

    可以使用 cy.exec() 启动和停止服务器,但我没有尝试。

    如果可以重新启动服务器,那么 mocks.json 可以在测试内部进行更改,但我很高兴在静态文件中设置mock,因为它降低了复杂性。