Advertisement
Guest User

Untitled

a guest
Apr 21st, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.24 KB | None | 0 0
  1. # In my test env config I have this set up, as a mock for Nadia
  2. test.exs ->
  3. config :shards_of_ocarion, :tg_sender, ShardsOfOcarionWeb.Senders.TestTelegramSender
  4.  
  5. # Here is how it is mocked
  6. defmodule ShardsOfOcarionWeb.Senders.TestTelegramSender do
  7.   def send_message(_, text, _ \\ []) do
  8.     send self, {:message_sent, text}
  9.   end
  10. end
  11.  
  12. #Here is the module that uses Nadia or that mock to send messages
  13. defmodule ShardsOfOcarionWeb.Senders.TelegramSender do
  14.   def send_message(chat_id, text, options \\ []) do
  15.     sender_module().send_message(chat_id, text, options)
  16.   end
  17.  
  18.   defp sender_module() do
  19.     Application.get_env(:shards_of_ocarion, :tg_sender)
  20.   end
  21. end
  22.  
  23. # And this module is in charge of sending generic messages. I want to test, that it sends after_sign_up_message
  24. defmodule ShardsOfOcarionWeb.Senders.Generic do
  25.   def after_sign_up_message(chat_id, user_name) do
  26.     text = "Добро пожаловать в игру, #{user_name}"
  27.     ShardsOfOcarionWeb.Senders.TelegramSender.send_message(chat_id, text)
  28.   end
  29. end
  30.  
  31. # With this test. The test passes, as expected.
  32. defmodule ShardsOfOcarionWeb.Senders.GenericTest do
  33.   use ExUnit.Case
  34.   # doctest ShardsOfOcarion
  35.  
  36.   describe "#after_sign_up_message" do
  37.     test "sends after_sign_up_message" do
  38.       user_name = "Tharin"
  39.       ShardsOfOcarionWeb.Senders.Generic.after_sign_up_message(1, user_name)
  40.       assert_received {:message_sent, "Добро пожаловать в игру, Tharin"}
  41.     end
  42.   end
  43. end
  44.  
  45. # But then I have this module
  46. defmodule ShardsOfOcarion.Game.Flows.Player.SignUpFlow do
  47.   alias ShardsOfOcarion.Players
  48.   alias ShardsOfOcarion.Players.Player
  49.  
  50.   def call(chat_id, user_name, "/start") do
  51.     case Players.create_player(%{tg_nickname: user_name}) do
  52.       %Player{} ->
  53.         ShardsOfOcarionWeb.Senders.Generic.after_sign_up_message(chat_id, user_name)
  54.         {:ok, :signed_up}
  55.       _         ->
  56.         ShardsOfOcarionWeb.Senders.Errors.could_not_sign_up(chat_id)
  57.         {:error, :could_not_sign_up}
  58.     end
  59.   end
  60. end
  61.  
  62. # And I have a dilemma. I've been taught not to excessively test everything, because it makes tests slower. If I already have after_sign_up_message covered with tests that it actually sends a message, I don't need it to run here again. It slows the test. Not significantly, but make 5000 of such tests and there is a difference, IMO. As I've got this covered with tests, all I need to test is that when .create_player returns a %Player{}, a message is being sent afterwards. As I've already said, I come from Ruby world and have a habit to allow().to receive() . What can I do here? Maybe, my code is just bad and there is a proper way to write it, so it becomes easily testable? I can't inject every module everywhere as a dependency to override it with test-purpose modules as I did with TestTelegramSender module. Am I right, that I should only do that for external dependencies like Nadia? Then how should I test this if using libraries such as Mock is highly discouraged? I googled the hell out of the internet and the most useful thing I found was this link: https://bhserna.com/testing-functions-with-side-effects-in-elixir.html . It helped me to test my Senders.Generic module, but it didn't tell me how to test modules that use it.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement