module Sentry::TestHelper

def clear_sentry_events

def clear_sentry_events
  return unless Sentry.initialized?
  sentry_transport.clear if sentry_transport.respond_to?(:clear)
  if Sentry.configuration.enable_logs && sentry_logger.respond_to?(:clear)
    sentry_logger.clear
  end
end

def extract_sentry_exceptions(event)

Returns:
  • (Array) -
def extract_sentry_exceptions(event)
  event&.exception&.values || []
end

def last_sentry_event

Returns:
  • (Event, nil) -
def last_sentry_event
  sentry_events.last
end

def reset_sentry_globals!

def reset_sentry_globals!
  Sentry::MUTEX.synchronize do
    # Don't check initialized? because sometimes we stub it in tests
    if Sentry.instance_variable_defined?(:@main_hub)
      Sentry::GLOBALS.each do |var|
        Sentry.instance_variable_set(:"@#{var}", nil)
      end
      Thread.current.thread_variable_set(Sentry::THREAD_LOCAL, nil)
    end
  end
end

def sentry_envelopes

Returns:
  • (Array) -
def sentry_envelopes
  sentry_transport.envelopes
end

def sentry_events

Returns:
  • (Array) -
def sentry_events
  sentry_transport.events
end

def sentry_logger

Returns:
  • (Sentry::StructuredLogger, Sentry::DebugStructuredLogger) -
def sentry_logger
  Sentry.logger
end

def sentry_logs

def sentry_logs
  sentry_envelopes
    .flat_map(&:items)
    .select { |item| item.headers[:type] == "log" }
    .flat_map { |item| item.payload[:items] }
end

def sentry_metrics

def sentry_metrics
  sentry_envelopes
    .flat_map(&:items)
    .select { |item| item.headers[:type] == "trace_metric" }
    .flat_map { |item| item.payload[:items] }
end

def sentry_transport

Returns:
  • (Transport) -
def sentry_transport
  Sentry.get_current_client.transport
end

def setup_sentry_test(&block)

Returns:
  • (void) -

Other tags:
    Yieldparam: config -
def setup_sentry_test(&block)
  raise "please make sure the SDK is initialized for testing" unless Sentry.initialized?
  dummy_config = Sentry.configuration.dup
  # configure dummy DSN, so the events will not be sent to the actual service
  dummy_config.dsn = DUMMY_DSN
  # set transport to DummyTransport, so we can easily intercept the captured events
  dummy_config.transport.transport_class = Sentry::DummyTransport
  # make sure SDK allows sending under the current environment
  dummy_config.enabled_environments ||= []
  dummy_config.enabled_environments += [dummy_config.environment] unless dummy_config.enabled_environments.include?(dummy_config.environment)
  # disble async event sending
  dummy_config.background_worker_threads = 0
  # user can overwrite some of the configs, with a few exceptions like:
  # - include_local_variables
  # - auto_session_tracking
  block&.call(dummy_config)
  # the base layer's client should already use the dummy config so nothing will be sent by accident
  base_client = Sentry::Client.new(dummy_config)
  Sentry.get_current_hub.bind_client(base_client)
  # create a new layer so mutations made to the testing scope or configuration could be simply popped later
  Sentry.get_current_hub.push_scope
  test_client = Sentry::Client.new(dummy_config.dup)
  Sentry.get_current_hub.bind_client(test_client)
end

def teardown_sentry_test

Returns:
  • (void) -
def teardown_sentry_test
  return unless Sentry.initialized?
  clear_sentry_events
  # pop testing layer created by `setup_sentry_test`
  # but keep the base layer to avoid nil-pointer errors
  # TODO: find a way to notify users if they somehow popped the test layer before calling this method
  if Sentry.get_current_hub.instance_variable_get(:@stack).size > 1
    Sentry.get_current_hub.pop_scope
  end
  Sentry::Scope.global_event_processors.clear
end