Cypress 组件测试拦截 getServerSideProps 请求

2024-02-01

使用 cypress 组件测试时无法弄清楚如何拦截 getServerSideProps。

做了很多研究和最好的线索链接:

https://github.com/cypress-io/cypress/discussions/9328 https://github.com/cypress-io/cypress/discussions/9328

https://www.youtube.com/watch?v=33Hq41O0bvU https://www.youtube.com/watch?v=33Hq41O0bvU

https://glebbahmutov.com/blog/mock-network-from-server/ https://glebbahmutov.com/blog/mock-network-from-server/

有这个示例仓库:https://github.com/norfeldt/proper/tree/ssr-stubing https://github.com/norfeldt/proper/tree/ssr-stubing

我尝试做的是:

赛普拉斯/插件/index.ts

const http = require('http');
const next = require('next');
const nock = require('nock');

// start the Next.js server when Cypress starts
module.exports = async (on, config) => {
  const app = next({ dev: true });
  const handleNextRequests = app.getRequestHandler();
  await app.prepare();

  on('dev-server:start', async () => {
    const customServer = new http.Server(async (req, res) => {
      return handleNextRequests(req, res);
    });
    await new Promise<void>((resolve, reject) => {
      customServer.listen(3000, err => {
        if (err) {
          return reject(err);
        }
        console.log('> Ready on http://localhost:3000');
        resolve();
      });
    });

    return customServer;
  });

  on('task', {
    clearNock() {
      nock.restore();
      nock.clearAll();

      return null;
    },

    async nock({ hostname, method, path, statusCode, body }) {
      nock.activate();

      console.log({ hostname, method, path, statusCode, body });

      method = method.toLowerCase();
      nock(hostname)[method][path].reply(statusCode, body);

      return null;
    },
  });

  return config;
};

组件/AddProperty/index.spec.ct.tsx

import { mount } from '@cypress/react';
import Component from './index';

beforeEach(() => {
  cy.task('clearNock');
});

it.only('queries the api', () => {
  cy.fixture('properties').then((properties: Property[]) => {
    cy.task('nock', {
      path: '/api/address?q=*',
      method: 'GET',
      statusCode: 200,
      body: {
        json: function () {
          return [{ id: '42', adressebetegnelse: 'Beverly Hills' } as Partial<Property>];
        },
      },
    });
    cy.intercept('GET', '/api/address?q=*', properties).as('getProperties');

    mount(<Component />);

    cy.contains('Beverly Hills');

    cy.get('input').type('Some address{enter}');

    cy.wait('@getProperties').its('response.statusCode').should('eq', 200);

    properties.forEach(property => {
      cy.contains(property.adressebetegnelse);
    });
  });
});

但它甚至不会运行测试


您有一个使用的组件测试mount()编译和托管组件。这实际上是一个“正常”的 React 测试,因为mount()来自“@cypress/react”是react-testing-library的包装器。

因此,您不是在测试 Next,而是在测试 React。

注意getServerSideProps不是由您的组件显式调用的,因此您在测试中或插件中所做的任何操作都不会对其进行测试。


我使用上面链接的 Gleb 示例进行了测试,替换了您的应用程序并创建了一个涉及 NextJS 的集成测试(因此调用getServerSideProps).

这些是我必须改变的关键事情

  • move getServerSideProps到一个页面(我使用主页)。 NextJS 不会在组件上调用它

  • 改变拼写(你有getServersideProps)

  • 添加一个返回值getServerSideProps

  • 去掉cy.intercept,因为nock任务正在做拦截

这是测试

it.only('queries the api', () => {

  cy.task('nock', {
    hostname: 'http://localhost:3000',
    method: 'GET',      
    path: '/api/address',
    statusCode: 200,
    body: {
      json: function () {
        return [{ id: '42', adressebetegnelse: 'Beverly Hills' }];
      },
    },
  });

  cy.visit('http://localhost:3000')
  cy.contains('Beverly Hills')       // this is what comes from ssrProps

在插件/索引中,我将 nock 拦截器更改为

nock(hostname)[method](path)
  .query(true)
  .reply((uri, requestBody) => {
    console.log('nock uri', uri)
    return [
      200,
      { id: '42', adressebetegnelse: 'Beverly Hills' }
    ]
  })

where query(true)仅接受任何查询参数。使用回调.reply()允许控制台日志检查它是否正在捕获请求。

这是获取 ssrProps 的主页。

import PropertyList from '../components/PropertyList/index.js'
import Link from 'next/link'

export default function Home(props) {

  return (
    <div>
      <h1>Portfolio</h1>
      <PropertyList />
      <Link href="/add">Tilføj ejendom</Link>

      <!-- outputting the ssrProps value here -->
      <div>{props.ssrProps.adressebetegnelse}</div>

    </div>
  )
}

export async function getServerSideProps(context) {

  const res = await fetch(`http://localhost:3000/api/address?q=strandvejen`)   
  const data = await res.json()

  return {    
    props: {
      ssrProps: data
    },
  }
}

从评论来看,

将集成测试SSR模拟请求转换为组件测试不容易吗?

我仍然认为这是不可能的,并且违背了每种测试类型的目的。 SSR 包括服务器,要测试它,您需要 e2e 测试 - 线索就在名称中。

组件测试是扩展的单元测试 - 它执行自己的安装并忽略服务器。

要在组件测试中测试 SSR,您必须扩展mount()在某种程度上,给你额外的代码和潜在的错误。当 e2e 测试相当简单并且能够完成工作时,IMO 毫无意义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cypress 组件测试拦截 getServerSideProps 请求 的相关文章

随机推荐

  • 如何在 Swift 中访问应用程序包中包含的文件?

    我知道有一些与此相关的问题 但它们是在 Objective C 中的 我怎样才能访问 txt使用 Swift 包含在我的应用程序中的文件在实际的 iPhone 上 我希望能够从中读取和写入 Here https github com gho
  • 如何在 Postgresql 命令行中指定要运行 sql 文件的架构

    我像这样针对我的数据库运行脚本 psql d myDataBase a f myInsertFile sql 唯一的问题是我希望能够在此命令中指定运行脚本的模式 我可以调用 set search path my schema 01 但文件应
  • Azure Devops 发布管道 XML 变量替换不起作用

    我的发布管道中有一个非常简单的变量替换 但它不起作用 我有变量connectionStrings config文件如下
  • 是什么导致 sprof 抱怨“ld.so 检测到的不一致”?

    我正在尝试使用 sprof 来分析一些软件 ossim 其中几乎所有代码都在共享库中 我已经生成了一个分析文件 但是当我运行 sprof 时 出现以下错误 gt sprof home eca7215 usr lib libossim so
  • 在 Query 上使用 keepSynced() 而不是在 DatabaseRef 上使用有什么区别吗?

    我目前正在从 Firebase 获取单个 dataSnapshot 如下所示 public Task
  • 将 netcat 与 bash 上的聊天结合起来以实现自动 udp 响应

    我想在 Linux 上结合 chat 和 nc 所以我将创建一个小型 udp 服务器 它响应特定请求并发回答案 事实上 我想将 nc 的标准输出重定向到 聊天 的标准输入 反之亦然 我的第一次尝试是 nc w 3000 u n l p 30
  • 禁用访问日志中的查询字符串

    长话短说 用户密码通过 url 传递纯文本 可怕 是的 但不是我的想法 并且此查询字符串存储在访问日志中 我们显然不希望如此明显 有没有办法在不禁用 CustomLog 的情况下防止查询字符串存储在访问日志中 Your common日志格式
  • 多线程Windows服务的线程库[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将 UITextField 增加到一定长度

    我有一个 UITextField 我想 自动 调整其边界大小 以便为字段中添加的字符串腾出空间 但是 我希望它的宽度达到一定程度的最大值 我可以采取的最佳方法是什么 谢谢你的帮助 EDIT 测试视图 h import
  • Haskell —— 是否有元组的 monad 序列函数?

    假设我有一个类型的值Monad m gt m a m a 我想对这对进行 排序 以创建类型的值Monad m gt m a a 它以与 序列 函数相同的方式组合两个值的单子上下文 是否有一些标准功能或标准方法可以做到这一点 这个操作还有意义
  • 每个页面加载的计时器减量都会有所不同

    我的项目有一个计时器 每次减少 1 秒 但是 如果计数器第二次开始工作 它会减少 2 秒 第三次则减少 3 秒 依此类推 我应该怎么做才能始终减少 1 秒 void viewDidAppear BOOL animated count 15
  • 计算大于另一个整数 x 的 k 位集合的最小整数?

    我想精确地计算最小整数k位设置 大于另一个整数x 例如如果x 1001010然后 为了k 2 答案应该是1010000 for k 4 答案应该是1001011并为k 5答案是1001111 我认为需要设置至少与整数中最左边设置的位一样多的
  • JSHint 奇怪的行为

    我认为我应该问关于 jSHint 的新问题 讨论开始了here https stackoverflow com questions 35987052 js strange behavior 我现在可以看到来自 JSHint 的奇怪警告 我只
  • 从 KMS CipherTextBlob 获取 KMS 密钥

    如何从密文 blob 中获取 KMS 密钥信息 以aws网站为例 AWS KMS 文档 http docs aws amazon com cli latest reference kms encrypt html aws kms encry
  • Matlab 和 XTickLabel

    我已经尝试让 Matlab 更改轮廓图上的标签大约一个小时了 当我去更改 XTickLabel 或 XTick 时 它只是完全删除我的 x 轴 令人沮丧和愤怒的是我正在做的事情exactly什么所有的帮助页面 http www mathwo
  • 使用 Git 版本控制查看文件的更改历史记录

    如何查看单个文件的历史记录以及更改内容的完整详细信息 git log filename 显示文件的提交历史记录 但如何查看已更改的文件内容 这让 Git 为每个日志条目生成补丁 git log p filename See git help
  • 如何使css/images/js文件等所有静态文件不被asp.net mvc处理?

    静态文件有可能不被asp net mvc引擎处理吗 我可以在 IIS 级别或其他级别执行此操作吗 当然无需为静态文件创建单独的 IIS 网站 您需要为不希望通过 ASP NET MVC 提供服务的特定类型的文件创建忽略路由 针对您要忽略的文
  • 切换 kivy 小部件

    我正在使用 Kivy python 库 我定义了两个小部件 当程序运行时 我运行第一个小部件 当按下该小部件按钮时 我希望它消失并被第二个小部件替换 这是两个小部件的 kv uitest kv
  • 确定 MouseListener 中单击的 JPanel 组件。事件处理

    我有一个扩展 JPanel 的类 public class ButtonPanel extends JPanel private label public ButtonPanel label new JLabel waiting for c
  • Cypress 组件测试拦截 getServerSideProps 请求

    使用 cypress 组件测试时无法弄清楚如何拦截 getServerSideProps 做了很多研究和最好的线索链接 https github com cypress io cypress discussions 9328 https g