skyqrose
How to mock phoenix sockets in Jest?
I want to test my js app that uses phoenix.js sockets. I want to write tests along the lines of:
- Set up a mocked socket and channel.
- Render my app.
- Interact with the app.
- Assert that a message was sent on the channel.
- Mock a response to that message as if the server had replied.
- Assert that the UI was updated with the response.
Is there a recommended way to do this?
I’m familiar with using jest to mock functions, but I’m struggling to set it up through the layers of callbacks and classes in a way that lets me assert something was pushed or send a reply.
First Post!
regan-karlewicz
Sorry, I’m a bit late to the party here.
Using vitest, I was able to accomplish creating a phoenix channel mock doing something like this:
import { vi } from 'vitest';
import * as phoenix from 'phoenix';
vi.mock('phoenix', () => {
return {
Socket: vi.fn().mockImplementation(() => fakeSocket)
};
});
const fakeChannel = {
join: vi.fn().mockReturnThis(),
push: vi.fn().mockReturnThis(),
on: vi.fn().mockReturnThis(),
off: vi.fn().mockReturnThis(),
leave: vi.fn().mockReturnThis(),
receive: vi.fn().mockImplementation((event, callback) => {
if (event === 'ok') {
callback({});
}
return this;
})
};
const fakeSocket = {
connect: vi.fn(),
channel: vi.fn(() => fakeChannel),
// mock any other used Socket class methods here
};
Then inside of your tests, you can override the mocks as needed:
describe("Example", () => {
it("can join a channel", async () => {
await joinChannel(); // This is the `socket.channel(...).join().receive("ok", callback)` wrapped by a promise that resolves in the callback
expect(fakeSocket.connect).toHaveBeenCalledOnce();
expect(fakeChannel.join).toHaveBeenCalledOnce();
});
it("can receive pushed event", async () => {
await joinChannel();
fakeChannel.on.mockImplementation((event, handler) => {
if (event == "pushed:event") handler("Some data");
return fakeChannel;
});
const result = await listenForPushedEvent(); // This is the function that sets up `channel.on("pushed:event", callback)` wrapped in a promise that resolves in the callback
expect(result).toEqual("Some data");
});
});
The challenge still exists that you have to carefully craft your mocks, which can be difficult since the Phoenix JS API is callback based.
0
Popular in Questions
How to bind a phoenix app to a specific ip address?
could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service.
Currently when I de...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
can someone please explain to me how Enum.reduce works with maps
New
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
Other popular topics
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible.
total = 10
while total != 0
...
New
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
Hello everyone,
I try to use an Javascript Event Handler in my root.html.leex file.
Therefore I created a function in the app.js file: ...
New
Hey all,
I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Hi all,
I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I’m trying to use Postgres...
New
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something…
Haskell reminds me of Java, and e...
New
Hi everyone!
I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










