Unit Testing the Survey Results State
Let's learn how to perform unit testing on a LiveView component.
We’ll begin with some unit tests that cover the SurveyResultsLive
component’s ability to manage survey results data in state. First up is the assign_products_with_average_ratings/2
reducer function, which needs to handle both an empty survey results dataset and one with existing product ratings. First, we’ll make sure the reducer creates the correct socket state when no product ratings exist.
Defining the Test module
We started by defining a test module in pento/test/pento_web/live/survey_results_live_test.exs
, like this:
defmodule PentoWeb.SurveyResultsLiveTest douse Pento.DataCasealias PentoWeb.SurveyResultsLive
Note the use Pento.DataCase
line. This pulls in the Pento.DataCase
behavior that provides access to the ExUnit testing functions and provides our test with a connection to the application’s test database.
We’ll also notice that our module aliases the SurveyResultsLive
component. That’s the component we’re testing in this module. We need to perform a few other aliases too. We’ll use them to establish some fixtures and helper functions to simplify the creation of test data, and we defined them in pento/test/pento_web/live/survey_results_live_test.exs
like this:
alias Pento.{Accounts, Survey, Catalog}@create_product_attrs %{description: "test description",name: "Test Game",sku: 42,unit_price: 120.5}@create_user_attrs %{email: "test@test.com",password: "passwordpassword"}@create_user2_attrs %{email: "another-person@email.com",password: "passwordpassword"}@create_demographic_attrs %{gender: "female",year_of_birth: DateTime.utc_now.year - 15}@create_demographic2_attrs %{gender: "male",year_of_birth: DateTime.utc_now.year - 30}defp product_fixture do{:ok, product} = Catalog.create_product(@create_product_attrs)productenddefp user_fixture(attrs \\ @create_user_attrs) do{:ok, user} = Accounts.register_user(attrs)userenddefp demographic_fixture(user, attrs \\ @create_demographic_attrs) doattrs =attrs|> Map.merge(%{user_id: user.id}){:ok, demographic} = Survey.create_demographic(attrs)demographicenddefp rating_fixture(stars, user, product) do{:ok, rating} = Survey.create_rating(%{stars: stars,user_id: user.id,product_id: product.id})ratingenddefp create_product(_) doproduct = product_fixture()%{product: product}enddefp create_user(_) douser = user_fixture()%{user: user}enddefp create_rating(stars, user, product) dorating = rating_fixture(stars, user, product)%{rating: rating}enddefp create_demographic(user) dodemographic = demographic_fixture(user)%{demographic: demographic}enddefp create_socket(_) do%{socket: %Phoenix.LiveView.Socket{}}end
Test fixtures create test data, and ours use module attributes to create User
, Demographic
, Product
, and Rating
records, followed by a few helpers that call on our fixtures and return the newly created records. We’ll see these helper functions, and their return values, in action in a bit.
Now that our test module is defined and we’ve implemented helper functions to create test data, we’re ready to write our very first test. We’ll start with a test that verifies the socket state when there are no product ratings. We add a call to the setup/1
function with the list of helpers that will create a user, product, and socket struct in this file ...