Module: Sentry::TestHelper

Defined in:
lib/sentry/test_helper.rb

Constant Summary collapse

DUMMY_DSN =
"http://12345:[email protected]/sentry/42"
REAL_DSN =

Not really real, but it will be resolved as a non-local for testing needs

"https://user:[email protected]/project/42"

Class Method Summary collapse

Class Method Details

.clear_sentry_eventsObject



65
66
67
68
69
70
71
72
73
# File 'lib/sentry/test_helper.rb', line 65

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

.extract_sentry_exceptions(event) ⇒ Array<Sentry::SingleExceptionInterface>

Extracts SDK’s internal exception container (not actual exception objects) from an given event.



112
113
114
# File 'lib/sentry/test_helper.rb', line 112

def extract_sentry_exceptions(event)
  event&.exception&.values || []
end

.last_sentry_eventEvent?

Returns the last captured event object.

Returns:



106
107
108
# File 'lib/sentry/test_helper.rb', line 106

def last_sentry_event
  sentry_events.last
end

.reset_sentry_globals!Object



116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/sentry/test_helper.rb', line 116

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

.sentry_envelopesArray<Envelope>

Returns the captured envelope objects.

Returns:



93
94
95
# File 'lib/sentry/test_helper.rb', line 93

def sentry_envelopes
  sentry_transport.envelopes
end

.sentry_eventsArray<Event>

Returns the captured event objects.

Returns:



87
88
89
# File 'lib/sentry/test_helper.rb', line 87

def sentry_events
  sentry_transport.events
end

.sentry_loggerSentry::StructuredLogger, Sentry::DebugStructuredLogger



76
77
78
# File 'lib/sentry/test_helper.rb', line 76

def sentry_logger
  Sentry.logger
end

.sentry_logsObject



97
98
99
100
101
102
# File 'lib/sentry/test_helper.rb', line 97

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

.sentry_transportTransport

Returns:



81
82
83
# File 'lib/sentry/test_helper.rb', line 81

def sentry_transport
  Sentry.get_current_client.transport
end

.setup_sentry_test {|config| ... } ⇒ void

This method returns an undefined value.

Alters the existing SDK configuration with test-suitable options. Mainly:

  • Sets a dummy DSN instead of ‘nil` or an actual DSN.

  • Sets the transport to DummyTransport, which allows easy access to the captured events.

  • Disables background worker.

  • Makes sure the SDK is enabled under the current environment (“test” in most cases).

It should be called before every test case.

Yield Parameters:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/sentry/test_helper.rb', line 22

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.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

.teardown_sentry_testvoid

This method returns an undefined value.

Clears all stored events and envelopes. It should be called after every test case.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sentry/test_helper.rb', line 51

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