mocking server for SSR react app e2e tests with cypress.io

巧了我就是萌 提交于 2019-12-23 01:04:20

问题


I'm building a single page web application (SPA) with server side rendering (SSR).

We have a node backend API which is called both from the node server during SSR and from the browser after initial rendering.

I want to write e2e tests that configures API responses (like with nock) and work both with browser calls and SSR server calls. some pseudo-code :

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');
})   

Currently Cypress allows me to mock fetch on the browser but not on the server.

Is there anything to achieve that ? Preferably with node libs.


回答1:


We used a particularly ugly solution, that breaks the speed of cypress, but we needed that in order to mock/fake socket calls.

You can make a real simple express server that starts before running your tests. This 'real fake server' will be able to respond what you need. Here are the specs of our:

  • POST on / with method, path and {data} in body params in order to setup a route
  • GET/POST/PUT/DELETE on /path responds {data}
  • DELETE on / clear all the routes

Let's consider your 'real fake server' run on 0.0.0.0:3000; you'll do:

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');
}) 

Important : the resquests need to be in localhost. You won't be able to stub something external. (Hence, make an env var in order to request localhost:xxxx instead of google.com when you test your app)

You won't be able to control the 'real fake server' otherwise than this cy.request because your tests scripts run in the browser (correct me if I'm wrong) and the browser can't run an express server.




回答2:


MockTTP can do that. Excerpt from the doc :

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");
        });
    );
});


来源:https://stackoverflow.com/questions/47631821/mocking-server-for-ssr-react-app-e2e-tests-with-cypress-io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!