Is the test LiveView immutable or not?
Someone from my Testing LiveView course recently asked me about the
immutability of the view
we get from live/2
in LiveView tests.
In the test, we clicked on an element, and then we used the open_browser/2
function to debug the test. Imagine something like this:
test "when users click 'Greet', they see a greeting", %{conn: conn} do
{:ok, view, _html} = live(conn, "/")
view
|> element("#greet", "Greet")
|> render_click()
# is the `view` here the one before or after the click?
open_browser(view)
end
Immutability question… we modify the view by clicking on an element… but at that point, the view variable contains the same view as before the click, cause nothing gets assigned to it.
How come the
open_browser
displays the updated view? I expected it to be in the state before the click because of the explanation above.
That’s an excellent question. Because, to be honest, something smells of mutation, right?
Variables are immutable. Process state isn’t.
The example above is confusing if we think of the view
merely as an in-memory
LiveView struct. So, when we use element/3
and render_click/2
, we
believe we’re only performing data transformations like we would with other
immutable data.
But in LiveView tests, the view
has a pointer to a client proxy (that acts
in place of a browser), which in turn interacts with our LiveView process. So,
when we click a button, we’re actually updating the state of the process and
re-rendering the HTML.
Thus, even though the view
variable is immutable, the LiveView state can
change, and therefore, the HTML rendered can change too.