【问题标题】:mocking server for SSR react app e2e tests with cypress.io使用 cypress.io 模拟 SSR 反应应用程序 e2e 测试的服务器
【发布时间】:2018-05-17 19:51:35
【问题描述】:

我正在构建一个带有服务器端渲染 (SSR) 的单页 Web 应用程序 (SPA)。

我们有一个节点后端 API,它在 SSR 期间从节点服务器调用,在初始渲染后从浏览器调用。

我想编写配置 API 响应的 e2e 测试(例如使用 nock)并同时使用浏览器调用和 SSR 服务器调用。一些伪代码:

it('loads some page (SSR mode)', () => {
  mockAPI.response('/some-path', {text: "some text"}); // here i configure the mock server response
  browser.load('/some-other-page'); // hit server for SSR response
  expect(myPage).toContain('some text');
})   

it('loads some other page (SPA mode)', () => {
  mockAPI.response('/some-path', {text: "some other text"}); // here i configure another response for the same call
  browser.click('#some-link'); // loads another page client side only : no SSR here
  expect(myPage).toContain('some other text');
})   

目前 Cypress 允许我在浏览器上模拟 fetch,但不能在服务器上模拟 fetch。

有什么可以实现的吗? 最好使用节点库。

【问题讨论】:

    标签: node.js testing nock server-side-rendering cypress


    【解决方案1】:

    我们使用了一个特别丑陋的解决方案,它破坏了 cypress 的速度,但我们需要它来模拟/伪造套接字调用。

    您可以创建一个真正简单的快速服务器,在运行测试之前启动。这个“真正的假服务器”将能够响应您的需求。 以下是我们的规格:

    • / 上发布 methodpath{data} 在正文参数中以设置路线
    • /path 上的 GET/POST/PUT/DELETE 响应 {data}
    • DELETE on / 清除所有路由

    让我们考虑一下您的“真正的假服务器”在 0.0.0.0:3000 上运行;你会做的:

    beforeEach() {
       cy.request('DELETE', 'http://0.0.0.0:3000/');
    }
    
    it('loads some page (SSR mode)', () => {
      cy.request('POST', 'http://0.0.0.0:3000/', {
        method: 'GET',
        path: '/some-path', 
        data: {text: "some other text"}
      }) // here i tell my 'real fake server' to 
         // respond {text: "some other text"} when it receives GET request on /some-path
      browser.load('/some-other-page'); // hit server for SSR response
      expect(myPage).toContain('some text');
    })   
    
    it('loads some other page (SPA mode)', () => {
      cy.request('POST', 'http://0.0.0.0:3000/', {
        method: 'GET',
        path: '/some-path', 
        data: {text: "some other text"}
      }); // here i configure another response for the same call
      browser.click('#some-link'); // loads another page client side only : no SSR here
      expect(myPage).toContain('some other text');
    }) 
    

    重要:resquests 需要在 localhost 中。你将无法存根外部的东西。 (因此,当你测试你的应用程序时,为了请求 localhost:xxxx 而不是 google.com,创建一个 env var)

    除了这个 cy.request 之外,您将无法控制“真正的假服务器”,因为您的测试脚本在浏览器中运行(如果我错了,请纠正我)并且浏览器无法运行快速服务器.

    【讨论】:

    • 这就是我们最终所做的。我正在寻找现有的模拟服务器(最好在节点中)。我终于找到了:看看我的答案
    【解决方案2】:

    MockTTP 可以做到这一点。文档摘录:

    const superagent = require("superagent");
    const mockServer = require("mockttp").getLocal();
    
    describe("Mockttp", () => {
        // Start your server
        beforeEach(() => mockServer.start(8080));
        afterEach(() => mockServer.stop());
    
        it("lets you mock requests, and assert on the results", () =>
            // Mock your endpoints
            mockServer.get("/mocked-path").thenReply(200, "A mocked response")
            .then(() => {
                // Make a request
                return superagent.get("http://localhost:8080/mocked-path");
            }).then(() => {
                // Assert on the results
                expect(response.text).to.equal("A mocked response");
            });
        );
    });
    

    【讨论】:

    • 这是一个展示 Cypress + Mockttp 集成的示例 repo:github.com/mvasin/cypress-mockttp
    • 它能够模拟本地 API 路由吗?因为它们与您的 Next 应用在同一个端口上运行?
    • 我收到“网络请求失败,因为这个错误发生在每个钩子之前,我们跳过了所有剩余的测试。”我按照这些例子来做这封信。
    • MockServer 是一个类似的工具:mock-server.com
    • 你能用mock service worker添加一个例子吗?
    猜你喜欢
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 2020-05-11
    • 2010-12-05
    相关资源
    最近更新 更多