jack

jack

So I was taking a look at documentation and other people code as well to understand a bit more about LiveView and specially, how to test it.

I’m still a bit confuse about some things, so those are probably very basic questions but I would appreciate any possible help, tip or advice.

Let’s take this example.

import Plug.Conn
import Phoenix.ConnTest
import Phoenix.LiveViewTest
@endpoint MyEndpoint

test "disconnected and connected mount", %{conn: conn} do
  conn = get(conn, "/my-path")
  assert html_response(conn, 200) =~ "<h1>My Disconnected View</h1>"

  {:ok, view, html} = live(conn)
end

We have this test for “disconnected and connected mount”.
I have a couple of questions about this.
The first one is what the endpoint tag purpose, I still didn’t found about it in the docs (I’m a bit in a hurry so I’m not reading it sequentially, maybe that’s why)

Now, I wonder why would I test “disconnected” and then “connected” mount in the same test case.
But before that, what really does a “disconnected mount” mean? I’ve been searching for this both on Google and on docs, but didn’t found any clarification about it.

As I understand the LiveView Life-Cycle so far is like this:

You receive a regular HTTP Request, it triggers mount/3, then handle_params/3, then render/1, and return a stateless, regular Web Page as HTTP Response.
Then, a WebSocket connection will start triggering mount/3 → handle_params/3 → render/1 again.

What a disconnected mount mean in this cycle?


Just like in this code example above, I’ve found people testing “disconnected mount” in their code as well.

assert html_response(conn, 200) =~ "<h1>My Disconnected View</h1>"

Like this code suggest, I saw people testing it like this: If I render a table, I would test the table empty instead.

My question is how?
If I use mount/3 or handle_params/3 to load the contents of my page, like executing a query to populate a table, how do so I could test for an “empty table” if I’m receiving a page after the complete life-cycle?

Right now I’m prototyping an application to learn and practice LiveView, I have the table as LiveComponents, do I could test successfully passing one valid list to the live component with render_component/2 and asserting the result. This is because I can control the params received in a live component, so I can test it and assert that only one <td> was created if I only passed one element in the list as params.

But if I use the mount/3 function to fetch data testing the liveview page instead of an isolated component, I’ll not be able to ever see this table empty.
Isn’t that what I’m supposed to do? Isn’t mount/3 where I fetch data to prepare the page for the response?

So, what a “disconnected mount” means, and what is the difference to a connected mount?
Can I receive the HTTP response after mount/3 but before handle_params/3?
Can I have a mount/3 for the HTTP response and another mount/3 that will execute only after the WebSocket being stablished?
(Like not fetching data from database in the HTTP request but fetching after a Live Socket start?)

Additionally how can I, in a test, force a failed connection to the database?

Sorry, those are a lot of questions, but I’m still a bit lost about how to test things both on Phoenix as a whole but specially about LiveView. I was wondering for a good bit why people wasn’t using controllers but doing everything on LiveView for example, so is the LiveView supposed to be both Controller, View and Template?
(and possible all three in the same file since you can render a sigil/literal instead of creating a separate template…)

I’m having a lot of fun learning LiveView but I’m not sure on how to do it “right”, I mean, in an organised and well designed way.
Should I call my (context/model) functions directly from LiveView? Or is it a better design to create a Controller, call the Controller from the LiveView, and then this Controller will interact with the Context?
This is not how I’m seeing people use it but I thought that LiveView would only be another type of “View”, I was surprised about it acting as a Controller in a lot of code I’m consuming to learn from.

Thank you for taking your time to read this until the end.

Showing Posts 2 to 1

jack

jack OP

Thank you for taking your time to reply cmo!

Your explanation was very helpful, honestly I understood what a disconnect mount is for your reply only.
The docs was not very clear for me, and the talk… I had watched it before and just watch it a second time right now and although it’s entertaining, for someone who is already confused about it showing non-working code it’s not really helpful. I liked the talk and I learned some things but not really about the life cycle itself… :sweat_smile:

I will take a look at the course, thank you!

cmo

cmo

First mount is disconnected which creates the websocket connection, rest of it happens over websocket (until you redirect etc). You can call connected?(socket) and it will be false for the first mount. You can setup a page with loading placeholders for things here if you like, which will populate either on the connected mount or you could send(self(), {:load_some_thing, ...}) in the mount so you can load the page first or you can do it async and send a message back to the liveview to assign it later.

Should I call my context/module from the LiveView?

Yep. You don’t need much in the way of controllers if your site is all live views. I don’t think of my project in terms of Models, Controllers and Views. I just build a UI in LiveView and call functions in modules :slight_smile:.

To learn about the lifecycle, you might like to watch this talk

This course might be of use to you. They go through the lifecycle and more.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews