Mocky Balboa and Cypress
How to use Mocky Balboa with Cypress.
≥ 14.x.x
Installation
- pnpm
- npm
- yarn
pnpm add -D @mocky-balboa/cypress
npm install -D @mocky-balboa/cypress
yarn add -D @mocky-balboa/cypress
Usage
Using the commands provided results in a singleton instance of the Mocky Balboa client being setup on the window
object. The instance is only created the first time cy.mocky
is called.
Setup commands
The recommended approach is to register the commands. This requires importing the commands in your E2E tests support file, cypress/support/e2e.{js,jsx,ts,tsx}
by default.
- TypeScript
- JavaScript
// cypress/support/e2e.ts
import "@mocky-balboa/cypress/commands";
// cypress/support/e2e.js
import "@mocky-balboa/cypress/commands";
The "mocky" command
The primary command you'll be using in your tests is cy.mocky
. This accepts a callback parameter where you can setup and teardown your routes.
- TypeScript
- JavaScript
it("loads the correct users", async () => {
cy.mocky((mocky) => {
mocky.route("**/api/users", (route) => {
return route.fulfill({
status: 200,
body: JSON.stringify([
{ id: "user-1", name: "John Doe" },
{ id: "user-2", name: "Jane Doe" }
]),
headers: { "Content-Type": "application/json" },
});
});
});
// Visit the page of our application in the browser
cy.visit("/");
// Our mock above should have been returned on our server
cy.contains("John Doe");
});
it("loads the correct users", async () => {
cy.mocky((mocky) => {
mocky.route("**/api/users", (route) => {
return route.fulfill({
status: 200,
body: JSON.stringify([
{ id: "user-1", name: "John Doe" },
{ id: "user-2", name: "Jane Doe" }
]),
headers: { "Content-Type": "application/json" },
});
});
});
// Visit the page of our application in the browser
cy.visit("/");
// Our mock above should have been returned on our server
cy.contains("John Doe");
});
Configuring the client
You can specify custom connection options if you need to override the default options when connecting the client to the server using the mockySetConnectionOptions
command.
- TypeScript
- JavaScript
it("...", async () => {
// Make sure you call mockySetConnectionOptions before any calls to cy.mocky
cy.mockySetConnectionOptions({ port: 1234 });
cy.mocky((mocky) => {
// ...
});
});
it("...", async () => {
// Make sure you call mockySetConnectionOptions before any calls to cy.mocky
cy.mockySetConnectionOptions({ port: 1234 });
cy.mocky((mocky) => {
// ...
});
});
Asserting on a request with "mockyWaitForRequest"
If you want to assert on a request made on the server you can use the mockyWaitForRequest
command. To do this you need to also pass an "action" which is a callback that you expect to invoke the request you are waiting on. For example if we expect navigating to "/" to trigger our /api/users
request our action would look like () => cy.visit("/")
. You can run any code within an action provided it returns a Cypress Chainable
.
- TypeScript
- JavaScript
it("calls /api/users with the correct public API key", async () => {
cy
.mockyWaitForRequest(() => cy.visit("/"), "**/api/users")
.then((request) => {
expect(request.headers.get("X-Public-Api-Key")).to.equal(
"public-api-key",
);
});
});
it("calls /api/users with the correct public API key", async () => {
cy
.mockyWaitForRequest(() => cy.visit("/"), "**/api/users")
.then((request) => {
expect(request.headers.get("X-Public-Api-Key")).to.equal(
"public-api-key",
);
});
});
Limitations
- There is no support for using
path
onroute.fulfill
. This is due to the difficulties of integrating chainable commands to the asynchronous internal request interception. Instead you can read the file contents and pass it as a string to thebody
.cy.intercept
doesn't support stubbing binary responses which would be the only thing files can offer over declarative mocks. Trying to usepath
onroute.fulfill
will result in an error being thrown.
Further usage
- See the client guide for more information on how you can setup routes via the mocky client.
- See the route guide for more information on how you can interact interact with routes on
mocky.route
. - See the advanced page for more information on advanced usage and how the framework works under the hood.