julngomz

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

Where Next?

Popular Pragmatic Bookshelf topics Top

jon
Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online: p. 186 But...
New
belgoros
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84: bundle exec sequel...
New
simonpeter
When I try the command to create a pair of migration files I get an error. user=&gt; (create-migration "guestbook") Execution error (Ill...
New
AleksandrKudashkin
On the page xv there is an instruction to run bin/setup from the main folder. I downloaded the source code today (12/03/21) and can’t see...
New
adamwoolhether
When trying to generate the protobuf .go file, I receive this error: Unknown flag: --go_opt libprotoc 3.12.3 MacOS 11.3.1 Googling ...
New
hgkjshegfskef
The test is as follows: Scenario: Intersecting a scaled sphere with a ray Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) And s ← sphere...
New
New
AufHe
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113. Iteration A1 - Seeing the list of prod...
New
SlowburnAZ
Getting an error when installing the dependencies at the start of this chapter: could not compile dependency :exla, "mix compile" failed...
New
New

Other popular topics Top

PragmaticBookshelf
Take your Go skills to the next level by learning how to design, develop, and deploy a distributed service. Start from the bare essential...
New
New
ohm
Which, if any, games do you play? On what platform? I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
AstonJ
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
foxtrottwist
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
New
PragmaticBookshelf
Author Spotlight Jamis Buck @jamis This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
New
mindriot
Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
New

Sub Categories: