#Test GenServer and problem with assert_receive

5 messages · Page 1 of 1 (latest)

static pilot
#

For some time now, he has been trying to find the best solution for GenServer testing. The problem is that assert_receive has to specify the time when the message will arrive, sometimes it arrives on time and sometimes it crashes that the mailbox is empty. Do you have any cool solution for testing GenServers?

I have rewritten the code so that it is understandable to you

defmodule App.Consumer do
  use Broadway
  alias Broadway.Message

  def start_link(_args) do
    options = [
      name: __MODULE__,
      producer: [
        module: {
          BroadwayRabbitMQ.Producer,
          connection: Application.get_env(:app, :uri_rabbitmq),
          queue: "queue",
          on_failure: :reject,
          qos: [prefetch_count: 10],
          declare: [durable: true],
          bindings: [
            {"app", routing_key: "queue.read"}
          ],
          metadata: [:routing_key]
        },
        concurrency: 1
      ],
      processors: [
        default: [
          concurrency: System.schedulers_online()
        ]
      ]
    ]

    Broadway.start_link(__MODULE__, options)
  end

  def handle_message(_processor, message, _context) do
    messenger_pid = get_messenger_pid(message)

    Messenger.send_hook(messenger_pid, :message)
  end
end
defmodule App.Messenger do
  @moduledoc false

  def send_hook(messenger_pid, value, meta \\ %{})

  def send_hook(messenger_pid, value, meta) do
    if not is_nil(messenger_pid) do
      send(messenger_pid, {value, meta})
    end
  end
end
defmodule App.ConsumerTest do
  use App.DataCase
  alias App.Consumer

  import Mock

  setup_with_mocks([
    {Broadway.Message, [], [failed: fn _, _ -> nil end]}
  ]) do
    :ok
  end

  describe "Test Consumer" do
    @good_message ~s({
      "data":{      
         "uuid":"ec031400-1784-4e22-b117-cb62fc9e0398"
         "created_at":"2022-01-03T11:16:05",
      }
   })

    test "Test" do
      ConsumerMarket.handle_message(
        nil,
        %{
          data: @good_message,
          messenger_pid: self(),
          metadata: %{
            routing_key: "queue.read"
          }
        },
        nil
      )

      assert_receive {:message, _meta}, 100
    end
  end
end

With such a test, it probably won't be a problem. But if Consumer Broadway start GenServer Feed and Feed start Dynamic Supervisor GenServer JobTask and you have a lot of tests written then you will end up getting this error

test Test Consumer Market Read xxxx (App.ConsumerTest)
     Assertion failed, no matching message after 100ms
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:zzz, _meta}
     mailbox:
       pattern: {:zzz, _meta}
       value:   {:xxx, %{}}(test)
still matrix
static pilot
#

This is probably what I need, but I need to calmly check it

#

Thanks!

still matrix
#

Take your time!