Mock Pusher.js in your JavaScript tests with ease.
Using yarn:
yarn add --dev pusher-js-mock
Or using npm:
npm install -D pusher-js-mock
For more detailed examples, check out examples
directory
inside the project!
Also, you can check out the Docs for even more information.
If you need to mock a Pusher object in your tests that can subscribe to channel, it's best to use PusherMock.
import { PusherMock } from "pusher-js-mock";
// initializing PusherMock
const pusher = new PusherMock();
// subscribing to a Pusher channel
const channel = pusher.subscribe("my-channel");
// emitting an event
channel.emit("event-name");
If you want to check whether your callback is getting called properly, you can bind a callback to your channel, and then emit an event.
import { PusherMock } from "pusher-js-mock";
descibe("listening for an event", () => {
// initializing PusherMock
const pusher = new PusherMock();
// subscribing to a Pusher channel
const channel = pusher.subscribe("my-channel");
// define and attach a listener
const listener = jest.fn();
channel.bind("event-name", listener);
// emitting an event
channel.emit("event-name");
// Expect listener to have been called
expect(listener).toHaveBeenCalled();
});
The connection within pusher is mocked and can be used much like a channel channel. There's no need to subscribe to subscription as it's subscribed by default on pusher.
import { PusherMock } from "pusher-js-mock";
// initializing PusherMock
const pusher = new PusherMock();
// emitting connection event
pusher.connection.emit("event-name");
As with channels, you can also listen to connection for events.
import { PusherMock } from "pusher-js-mock";
descibe("listening for an event", () => {
// initializing PusherMock
const pusher = new PusherMock();
// define and attach a listener
const listener = jest.fn();
pusher.connection.bind("event-name", listener);
// emitting an event
pusher.connection.emit("event-name");
// Expect listener to have been called
expect(listener).toHaveBeenCalled();
});
If you're using Pusher in your code in this or similar manner:
import Pusher from "pusher-js";
You will need to mock Pusher in a specific way.
I suggest you use Jest to test your code. To do this in Jest, you'll need something like this:
jest.mock("pusher-js", () => {
const Pusher = require("pusher-js-mock").PusherMock;
return Pusher;
});
If you have tips on how to mock this using other testing frameworks, please submit an issue or a pull request.
This shows how to stub a pusher if you're attaching it to window object in your
project. If you're attaching a PusherFactory to a window
object like this in
your code:
window.PusherFactory = {
pusherClient: function(pusherKey) {
return new Pusher(pusherKey);
}
};
It's best for you to use PusherFactoryMock.
import { PusherFactoryMock } from "pusher-js-mock";
// initialize instance of PusherFactoryMock
const pusherFactoryMock = new PusherFactoryMock();
// replace it with the object that is attached to a window
window.PusherFactory = pusherFactoryMock;
// get the Pusher client reference
pusher = pusherFactoryMock.pusherClient();
This way you'll just replace your PusherFactory with PusherFactoryMock.
This package also supports using presence channels for multiple clients. The
mock will automatically detect when presence-
is in the channel name and
return a presence channel with channel.members
filled out as expected. You
can pass in IDs and info via a custom authorizer, just as you would with the
real package.
If you want, you can pass in a custom authorizer when creating a Pusher client.
// create-client.js
import Pusher from "pusher-js";
import { getAuthSomehow } from "./getAuthSomehow";
export const createClient = ({ id, info }) =>
new Pusher("APP_KEY", {
cluster: "APP_CLUSTER",
// see https://github.com/pusher/pusher-js#authorizer-function
authorizer: ({ name }) => ({
authorize: (socketId, callback) => {
const auth = getAuthSomehow(id, info);
callback(false, auth);
}
})
});
export default createClient;
// create-client.spec.js
import createClient from "../create-client";
// mock the authorize function and pusher
jest.mock("pusher-js", () => require("pusher-js-mock"));
jest.mock("../getAuthSomehow", () => ({
getAuthSomehow: (id, info) => ({ id, info })
}));
it("should create a presence channel", async () => {
// arrange: create pusher client
const pusher = createClient({ id: "my-id", info: { role: "moderator" } });
// act: required to ensure pusher events are called, i.e. pusher:member_added
const presenceChannel = await pusher.subscribe("presence-channel");
// assert: presenceChannel has the properties we expect it to.
expect(presenceChannel.members.myID).toBe("my-id");
expect(presenceChannel.members.me).toEqual({
id: "my-id",
info: { role: "moderator" }
});
expect(presenceChannel.members.members).toEqual({
"my-id": { role: "moderator" }
});
});
Check out a code example of using presence channels
The mocked Pusher instance will also emit pusher internal events
pusher:subscription_succeeded
, pusher:member_added
and
pusher:member_removed
to the relevant clients:
it("should emit presence-channel events", async () => {
const client = createClient({ id: "my-id" });
const channel = client.subscribe("presence-channel");
const listener = jest.fn();
/**
* On bind, pusher:subscription_succeded will trigger
* for the client subscribing. Other clients will be
* notified via pusher:member_added as below.
*/
await channel.bind("pusher:subscription_succeeded", listener);
expect(listener).toHaveBeenCalledTimes(1);
/**
* Create and subscribe a new client that will trigger the
* pusher:member_added event. This only gets triggered for
* clients are not the client subscribing
*/
channel.bind("pusher:member_added", listener);
const otherClient = createClient({ id: "your-id" });
await otherClient.subscribe("presence-channel");
expect(listener).toHaveBeenCalledTimes(2);
/**
* Unsubscribe the otherClient to trigger pusher:member_removed.
* This only gets triggered for clients that are not the client
* unsubscribing.
*/
channel.bind("pusher:member_removed", listener);
await otherClient.unsubscribe("presence-channel");
expect(listener).toHaveBeenCalledTimes(3);
});
Photo by Octavian Rosca on Unsplash
the channel we want to trigger this on
the client we're using to emit the connection events
void
Emit disconnection events triggered by pusher
the channel we want to trigger this on
the client we're using to emit the connection events
void
COPIED DIRECTLY FROM pusher-js PACKAGE
Proxy the channel bind function and attach owner id for conditions in channel.emit
The channel being proxied
The client we're using to proxy the channel
void
Proxy emit function and only trigger callbacks if conditions are correct, i.e.
The channel being proxied
The client we're using to proxy the channel
void
Proxy custom members info to
The original members property on the channel
The client we're using to proxy the channel
The proxied members property on the channel
Create the proxied channel
the channel to be proxied
the client we'll use to proxy the channel
the proxied channel
Generated using TypeDoc
Emit connection events triggered by pusher