Testing

Testing

Opt-in RSpec and Minitest helpers capture published events without touching PGMQ.

Set it up#

The testing module is never autoloaded — you require it.

The testing helpers are never loaded by Zeitwerk, so they can't leak into production. Require them, activate a mode, and clear the store per test.

spec/rails_helper.rb
require "pgbus/testing/rspec"

RSpec.configure do |config|
  config.before { Pgbus::Testing.fake! }
  config.after do
    Pgbus::Testing.disabled!
    Pgbus::Testing.store.clear!
  end
end

Minitest is the same shape — require pgbus/testing/minitest and include Pgbus::Testing::MinitestHelpers, which hooks the lifecycle automatically.

Testing modes#

Three modes control how Publisher.publish behaves in tests:

ModeBehaviorUse for
:fakeCaptures events in memory; no PGMQ, no dispatch.Most unit/integration tests.
:inlineCaptures AND dispatches to matching handlers.Testing handler side effects.
:disabledPass-through to the real publisher.Integration tests with real PGMQ.
Pgbus::Testing.fake!     # global
Pgbus::Testing.inline! do
  OrderService.create!(attrs) # handlers fire synchronously
end                           # previous mode restored after the block

Event-bus assertions#

Shared by RSpec and Minitest.

assert_pgbus_published(count: 1, routing_key: "orders.created") do
  OrderService.create!(attrs)
end

assert_no_pgbus_published(routing_key: "orders.created") do
  OrderService.preview(attrs)
end

# Capture, then dispatch to handlers — for testing side effects:
perform_published_events { OrderService.create!(attrs) }

The RSpec matcher#

have_published_event chains payload, header, and count constraints:

expect { publish_order(order) }
  .to have_published_event("orders.created")
  .with_payload(hash_including("id" => order.id))
  .with_headers(hash_including("x-tenant" => "acme"))
  .exactly(1)

expect { publish_order(order) }.not_to have_published_event("orders.cancelled")

SSE streams in tests#

SSE streams use rack.hijack, which spawns background threads that take their own database connections — incompatible with Rails' use_transactional_fixtures. pgbus detects the test environment and, under Pgbus::Testing.fake!/.inline!, auto-enables streams_test_mode: the streams endpoint returns a stub response with no hijack and no background threads, so your suite stays green without connection-pool surprises.

You rarely set streams_test_mode yourself — activating a testing mode turns it on for you.