👋 Welcome to pusher-js-mock
Mock Pusher.js in your JavaScript tests with ease.
Installing ⏬
Using yarn:
yarn add --dev pusher-js-mock
Or using npm:
npm install -D pusher-js-mock
Usage 🛠
For more detailed examples, check out examples
directory
inside the project!
Also, you can check out the
Docs for even more information.
Emitting an event 📶
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";
const pusher = new PusherMock();
const channel = pusher.subscribe("my-channel");
channel.emit("event-name");
Listening for an event 👂
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", () => {
const pusher = new PusherMock();
const channel = pusher.subscribe("my-channel");
const listener = jest.fn();
channel.bind("event-name", listener);
channel.emit("event-name");
expect(listener).toHaveBeenCalled();
});
Emitting an event from connection 📶
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";
const pusher = new PusherMock();
pusher.connection.emit("event-name");
Listening for an event from connection 👂
As with channels, you can also listen to connection for events.
import { PusherMock } from "pusher-js-mock";
descibe("listening for an event", () => {
const pusher = new PusherMock();
const listener = jest.fn();
pusher.connection.bind("event-name", listener);
pusher.connection.emit("event-name");
expect(listener).toHaveBeenCalled();
});
Stubbing Pusher when imported from pusher-js package 📦
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.
Stubbing Pusher when used as a global variable 🌍
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";
const pusherFactoryMock = new PusherFactoryMock();
window.PusherFactory = pusherFactoryMock;
pusher = pusherFactoryMock.pusherClient();
This way you'll just replace your PusherFactory with PusherFactoryMock.
Mocking presence channels
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.
Using custom authorizer
If you want, you can pass in a custom authorizer when creating a Pusher client.
import Pusher from "pusher-js";
import { getAuthSomehow } from "./getAuthSomehow";
export const createClient = ({ id, info }) =>
new Pusher("APP_KEY", {
cluster: "APP_CLUSTER",
authorizer: ({ name }) => ({
authorize: (socketId, callback) => {
const auth = getAuthSomehow(id, info);
callback(false, auth);
}
})
});
export default createClient;
import createClient from "../create-client";
jest.mock("pusher-js", () => require("pusher-js-mock"));
jest.mock("../getAuthSomehow", () => ({
getAuthSomehow: (id, info) => ({ id, info })
}));
it("should create a presence channel", async () => {
const pusher = createClient({ id: "my-id", info: { role: "moderator" } });
const presenceChannel = await pusher.subscribe("presence-channel");
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
Pusher events emitted by 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();
await channel.bind("pusher:subscription_succeeded", listener);
expect(listener).toHaveBeenCalledTimes(1);
channel.bind("pusher:member_added", listener);
const otherClient = createClient({ id: "your-id" });
await otherClient.subscribe("presence-channel");
expect(listener).toHaveBeenCalledTimes(2);
channel.bind("pusher:member_removed", listener);
await otherClient.unsubscribe("presence-channel");
expect(listener).toHaveBeenCalledTimes(3);
});
Credits
Photo by Octavian Rosca on Unsplash