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.
Popular in Questions
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
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
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
Hello, I get Persian date from my client and convert it to normal calendar like this:
def jalali_string_to_miladi_english_number(persi...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Hi everyone,
I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
Hi!
Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
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
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
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
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
After calling mix ecto.create I get this error:
17:00:32.162 [error] GenServer #PID<0.412.0> terminating
** (Postgrex.Error) FATAL...
New
Hello, how can I check the Phoenix version ?
Thanks !
New
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Hello guys,
I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
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
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









