
julngomz
Programming Phoenix LiveView B9: Testing Fails with the provided testing code. (pages 295 - 296)
Hello,
In chapter 10, Testing Your Live Views, the provided code is confusing. (Or I misread this passage)
Example Code
On page 295, when testing ratings by age group, the following code snippet is provided:
test "ratings are filtered by age group", ...<map>.. do
...
socket =
update_socket(socket, :age_group_filter, "18 and under")
|> SurveyResultsLive.assign_age_group_filter()
assert socket.assigns.age_group_filter == "18 and under"
...
end
defp update_socket(socket, key, value) do
%{socket | assigns: Map.merge(socket.assigns, Map.new([{key, value}]))}
end
Problem
So essentially what this piece of code was suppose to do is update the :age_group_filter
to 18 and under
, but what the the code provided actually does, is it updates the socket to 18 and under
but then it gets piped back through SurveyResultsLive.assign_age_group_filter()
reverting it back to all
.
The following is the code to update the :age_group_filter
in the SurveyResultsLive.assign_age_group_filter()
live component function.
def assign_age_group_filter(socket) do
assign(socket, :age_group_filter, "all")
end
def assign_age_group_filter(socket, age_group_filter) do
assign(socket, :age_group_filter, age_group_filter)
end
Since we are not passing a second parameter, the first implementation is matched. Assigning all
to :age_group_filter
once again. Resulting in a failed assertion:
assert socket.assigns.age_group_filter == "18 and under"
Snippet Rewrite
So essentially the testing code should be as the following:
...
socket = SurveyResultsLive.assign_age_group_filter(socket, "18 and under")
assert socket.assigns.age_group_filter == "18 and under"
...
the update_socket
helper function is essentially unnecessary and confusing, shouldn’t we leave the socket updates on to implementer not the tester?
Further Changes
If we follow the previous code, then on the next page (page 296), the resulting testing code should be:
socket
|> SurveyResultsLive.assign_gender_filter()
|> SurveyResultsLive.assign_age_group_filter()
|> assert_keys(:age_group_filter, "all")
|> SurveyResultsLive.assign_age_group_filter("18 and under")
|> assert_keys(:age_group_filter, "18 and under")
|> SurveyResultsLive.assign_age_group_filter()
|> SurveyResultsLive.assign_products_with_average_ratings()
|> assert_keys(:products_with_average_ratings, [{"Test Game", 2.0}])
This works as expected and looks much nicer without the update_socket
, but this also fails the last assertion test since we are creating two user ratings, the resulting average will change. The simple way to fix this is to change it to from 2.0
to 2.5
.
Or you can add a helper function such as the following:
defp calculate_average_rating(user_ratings) do
stars = for {_user, stars} <- user_ratings, do: stars
stars_count = length(stars)
stars_sum = Enum.sum(stars)
stars_sum / stars_count
end
...using within test...
user_ratings = [{user, 2}, {user2, 3}]
avg_rating = calculate_average_rating(user_ratings)
for {user, stars} <- user_ratings do
create_rating(stars, user, product)
end
...assertion test...
|> assert_keys(:products_with_average_ratings, [{"Test Game", avg_rating}])
where user_ratings
is a list of user rating tuples [{user, 2}, {user2, 3}]
and can be for looped to create multiple ratings
Popular Prag Prog topics










Other popular topics










Latest in PragProg
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /centos
- /ash
- /php
- /deepseek
- /zig
- /scala
- /html
- /debian
- /nixos
- /lisp
- /agda
- /sublime-text
- /textmate
- /react-native
- /kubuntu
- /arch-linux
- /ubuntu
- /revery
- /manjaro
- /spring
- /django
- /diversity
- /nodejs
- /lua
- /slackware
- /c
- /julia
- /neovim