karafka-testing 2.5.4 → 2.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lint.lock ADDED
@@ -0,0 +1,108 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ ast (2.4.3)
5
+ json (2.18.0)
6
+ language_server-protocol (3.17.0.5)
7
+ lint_roller (1.1.0)
8
+ parallel (1.27.0)
9
+ parser (3.3.10.1)
10
+ ast (~> 2.4.1)
11
+ racc
12
+ prism (1.8.0)
13
+ racc (1.8.1)
14
+ rainbow (3.1.1)
15
+ regexp_parser (2.11.3)
16
+ rubocop (1.82.1)
17
+ json (~> 2.3)
18
+ language_server-protocol (~> 3.17.0.2)
19
+ lint_roller (~> 1.1.0)
20
+ parallel (~> 1.10)
21
+ parser (>= 3.3.0.2)
22
+ rainbow (>= 2.2.2, < 4.0)
23
+ regexp_parser (>= 2.9.3, < 3.0)
24
+ rubocop-ast (>= 1.48.0, < 2.0)
25
+ ruby-progressbar (~> 1.7)
26
+ unicode-display_width (>= 2.4.0, < 4.0)
27
+ rubocop-ast (1.49.0)
28
+ parser (>= 3.3.7.2)
29
+ prism (~> 1.7)
30
+ rubocop-minitest (0.39.1)
31
+ lint_roller (~> 1.1)
32
+ rubocop (>= 1.75.0, < 2.0)
33
+ rubocop-ast (>= 1.38.0, < 2.0)
34
+ rubocop-performance (1.26.1)
35
+ lint_roller (~> 1.1)
36
+ rubocop (>= 1.75.0, < 2.0)
37
+ rubocop-ast (>= 1.47.1, < 2.0)
38
+ rubocop-thread_safety (0.7.3)
39
+ lint_roller (~> 1.1)
40
+ rubocop (~> 1.72, >= 1.72.1)
41
+ rubocop-ast (>= 1.44.0, < 2.0)
42
+ ruby-progressbar (1.13.0)
43
+ standard (1.53.0)
44
+ language_server-protocol (~> 3.17.0.2)
45
+ lint_roller (~> 1.0)
46
+ rubocop (~> 1.82.0)
47
+ standard-custom (~> 1.0.0)
48
+ standard-performance (~> 1.8)
49
+ standard-custom (1.0.2)
50
+ lint_roller (~> 1.0)
51
+ rubocop (~> 1.50)
52
+ standard-minitest (1.0.0)
53
+ lint_roller (~> 1.0)
54
+ rubocop-minitest
55
+ standard-performance (1.9.0)
56
+ lint_roller (~> 1.1)
57
+ rubocop-performance (~> 1.26.0)
58
+ unicode-display_width (3.2.0)
59
+ unicode-emoji (~> 4.1)
60
+ unicode-emoji (4.2.0)
61
+ yard (0.9.38)
62
+ yard-lint (1.4.0)
63
+ yard (~> 0.9)
64
+ zeitwerk (~> 2.6)
65
+ zeitwerk (2.7.4)
66
+
67
+ PLATFORMS
68
+ ruby
69
+ x86_64-linux
70
+
71
+ DEPENDENCIES
72
+ rubocop-minitest
73
+ rubocop-performance
74
+ rubocop-thread_safety
75
+ standard
76
+ standard-minitest
77
+ standard-performance
78
+ yard-lint
79
+
80
+ CHECKSUMS
81
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
82
+ json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
83
+ language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
84
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
85
+ parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
86
+ parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
87
+ prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254
88
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
89
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
90
+ regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
91
+ rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273
92
+ rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
93
+ rubocop-minitest (0.39.1) sha256=998398d6da4026d297f0f9bf709a1eac5f2b6947c24431f94af08138510cf7ed
94
+ rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
95
+ rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431
96
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
97
+ standard (1.53.0) sha256=f3c9493385db7079d0abce6f7582f553122156997b81258cd361d3480eeacf9c
98
+ standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b
99
+ standard-minitest (1.0.0) sha256=450caa86a64a6e6f6f186cc88601dbb49b6cfaa3b0dce77a73b50ba8cdc15b2a
100
+ standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2
101
+ unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
102
+ unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
103
+ yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
104
+ yard-lint (1.4.0) sha256=7dd88fbb08fd77cb840bea899d58812817b36d92291b5693dd0eeb3af9f91f0f
105
+ zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b
106
+
107
+ BUNDLED WITH
108
+ 4.0.3
data/Gemfile.lock CHANGED
@@ -1,46 +1,77 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka-testing (2.5.4)
4
+ karafka-testing (2.5.6)
5
5
  karafka (>= 2.5.0, < 2.6.0)
6
6
  waterdrop (>= 2.8.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- base64 (0.2.0)
12
- ffi (1.17.0)
13
- ffi (1.17.0-x86_64-linux-gnu)
14
- json (2.13.2)
15
- karafka (2.5.0)
11
+ base64 (0.3.0)
12
+ diff-lcs (1.6.2)
13
+ docile (1.4.1)
14
+ drb (2.2.3)
15
+ ffi (1.17.3)
16
+ ffi (1.17.3-x86_64-linux-gnu)
17
+ json (2.19.2)
18
+ karafka (2.5.1)
16
19
  base64 (~> 0.2)
17
- karafka-core (>= 2.5.2, < 2.6.0)
18
- karafka-rdkafka (>= 0.19.5)
19
- waterdrop (>= 2.8.3, < 3.0.0)
20
+ karafka-core (>= 2.5.6, < 2.6.0)
21
+ karafka-rdkafka (>= 0.22.0)
22
+ waterdrop (>= 2.8.9, < 3.0.0)
20
23
  zeitwerk (~> 2.3)
21
- karafka-core (2.5.6)
24
+ karafka-core (2.5.10)
22
25
  karafka-rdkafka (>= 0.20.0)
23
26
  logger (>= 1.6.0)
24
- karafka-rdkafka (0.21.0)
25
- ffi (~> 1.15)
27
+ karafka-rdkafka (0.24.0)
28
+ ffi (~> 1.17.1)
26
29
  json (> 2.0)
27
30
  logger
28
31
  mini_portile2 (~> 2.6)
29
32
  rake (> 12)
30
- karafka-rdkafka (0.21.0-x86_64-linux-gnu)
31
- ffi (~> 1.15)
33
+ karafka-rdkafka (0.24.0-x86_64-linux-gnu)
34
+ ffi (~> 1.17.1)
32
35
  json (> 2.0)
33
36
  logger
34
37
  mini_portile2 (~> 2.6)
35
38
  rake (> 12)
36
39
  logger (1.7.0)
37
- mini_portile2 (2.8.7)
38
- rake (13.2.1)
39
- waterdrop (2.8.3)
40
+ mini_portile2 (2.8.9)
41
+ minitest (6.0.2)
42
+ drb (~> 2.0)
43
+ prism (~> 1.5)
44
+ mocha (3.1.0)
45
+ ruby2_keywords (>= 0.0.5)
46
+ ostruct (0.6.3)
47
+ prism (1.9.0)
48
+ rake (13.3.1)
49
+ rspec (3.13.2)
50
+ rspec-core (~> 3.13.0)
51
+ rspec-expectations (~> 3.13.0)
52
+ rspec-mocks (~> 3.13.0)
53
+ rspec-core (3.13.6)
54
+ rspec-support (~> 3.13.0)
55
+ rspec-expectations (3.13.5)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.13.0)
58
+ rspec-mocks (3.13.7)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.13.0)
61
+ rspec-support (3.13.6)
62
+ ruby2_keywords (0.0.5)
63
+ simplecov (0.22.0)
64
+ docile (~> 1.1)
65
+ simplecov-html (~> 0.11)
66
+ simplecov_json_formatter (~> 0.1)
67
+ simplecov-html (0.13.2)
68
+ simplecov_json_formatter (0.1.4)
69
+ warning (1.5.0)
70
+ waterdrop (2.8.12)
40
71
  karafka-core (>= 2.4.9, < 3.0.0)
41
- karafka-rdkafka (>= 0.19.1)
72
+ karafka-rdkafka (>= 0.20.0)
42
73
  zeitwerk (~> 2.3)
43
- zeitwerk (2.6.16)
74
+ zeitwerk (2.7.3)
44
75
 
45
76
  PLATFORMS
46
77
  ruby
@@ -48,6 +79,12 @@ PLATFORMS
48
79
 
49
80
  DEPENDENCIES
50
81
  karafka-testing!
82
+ minitest
83
+ mocha
84
+ ostruct
85
+ rspec
86
+ simplecov
87
+ warning
51
88
 
52
89
  BUNDLED WITH
53
90
  2.6.3
data/Rakefile CHANGED
@@ -1,4 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/setup'
4
- require 'bundler/gem_tasks'
3
+ require "bundler/setup"
4
+ require "bundler/gem_tasks"
5
+
6
+ require "rake/testtask"
7
+
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << "test"
10
+ t.test_files = FileList["test/test_helper.rb", "test/**/*_test.rb"]
11
+ .exclude("test/integration/**/*")
12
+ end
13
+
14
+ task default: :test
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
- require 'karafka/testing/version'
6
+ require "karafka/testing/version"
7
7
 
8
8
  Gem::Specification.new do |spec|
9
- spec.name = 'karafka-testing'
10
- spec.platform = Gem::Platform::RUBY
11
- spec.version = Karafka::Testing::VERSION
12
- spec.authors = ['Maciej Mensfeld']
13
- spec.email = %w[contact@karafka.io]
14
- spec.summary = 'Library which provides helpers for easier Karafka consumers tests'
15
- spec.description = 'Library which provides helpers for easier Karafka consumers tests'
16
- spec.homepage = 'https://karafka.io'
17
- spec.license = 'MIT'
18
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
9
+ spec.name = "karafka-testing"
10
+ spec.platform = Gem::Platform::RUBY
11
+ spec.version = Karafka::Testing::VERSION
12
+ spec.authors = ["Maciej Mensfeld"]
13
+ spec.email = %w[contact@karafka.io]
14
+ spec.summary = "Library which provides helpers for easier Karafka consumers tests"
15
+ spec.description = "Library which provides helpers for easier Karafka consumers tests"
16
+ spec.homepage = "https://karafka.io"
17
+ spec.license = "MIT"
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test)/}) }
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = %w[lib]
21
21
 
22
- spec.add_dependency 'karafka', '>= 2.5.0', '< 2.6.0'
23
- spec.add_dependency 'waterdrop', '>= 2.8.0'
22
+ spec.add_dependency "karafka", ">= 2.5.0", "< 2.6.0"
23
+ spec.add_dependency "waterdrop", ">= 2.8.0"
24
24
 
25
- spec.required_ruby_version = '>= 3.2.0'
25
+ spec.required_ruby_version = ">= 3.2.0"
26
26
 
27
27
  spec.metadata = {
28
- 'homepage_uri' => 'https://karafka.io',
29
- 'changelog_uri' => 'https://karafka.io/docs/Changelog-Karafka-Testing',
30
- 'bug_tracker_uri' => 'https://github.com/karafka/karafka-testing/issues',
31
- 'source_code_uri' => 'https://github.com/karafka/karafka-testing',
32
- 'documentation_uri' => 'https://karafka.io/docs',
33
- 'rubygems_mfa_required' => 'true'
28
+ "homepage_uri" => "https://karafka.io",
29
+ "changelog_uri" => "https://karafka.io/docs/Changelog-Karafka-Testing",
30
+ "bug_tracker_uri" => "https://github.com/karafka/karafka-testing/issues",
31
+ "source_code_uri" => "https://github.com/karafka/karafka-testing",
32
+ "documentation_uri" => "https://karafka.io/docs",
33
+ "rubygems_mfa_required" => "true"
34
34
  }
35
35
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'karafka/testing'
4
- require 'karafka/testing/errors'
5
- require 'karafka/testing/helpers'
6
- require 'karafka/testing/spec_consumer_client'
7
- require 'karafka/testing/spec_producer_client'
8
- require 'karafka/testing/minitest/proxy'
3
+ require "karafka/testing"
4
+ require "karafka/testing/errors"
5
+ require "karafka/testing/helpers"
6
+ require "karafka/testing/spec_consumer_client"
7
+ require "karafka/testing/spec_producer_client"
8
+ require "karafka/testing/minitest/proxy"
9
9
 
10
10
  module Karafka
11
11
  module Testing
@@ -42,14 +42,23 @@ module Karafka
42
42
  Karafka.producer.stubs(:client).returns(@_karafka_producer_client)
43
43
  end
44
44
 
45
- if base.to_s == 'Minitest::Spec'
45
+ if base.to_s == "Minitest::Spec"
46
46
  base.class_eval do
47
47
  before(&eval_flow)
48
48
  end
49
- else
49
+ elsif base.respond_to?(:setup) && base.method(:setup).arity != 0
50
50
  base.class_eval do
51
51
  setup(&eval_flow)
52
52
  end
53
+ else
54
+ setup_mod = Module.new do
55
+ define_method(:setup) do
56
+ instance_exec(&eval_flow)
57
+ super()
58
+ end
59
+ end
60
+
61
+ base.prepend(setup_mod)
53
62
  end
54
63
  end
55
64
  end
@@ -89,11 +98,13 @@ module Karafka
89
98
  # @example Send a json message to consumer and simulate, that it is partition 6
90
99
  # @karafka.produce({ 'hello' => 'world' }.to_json, 'partition' => 6)
91
100
  def _karafka_add_message_to_consumer_if_needed(message)
92
- consumer_obj = if defined?(@consumer)
93
- @consumer
94
- else
95
- @_karafka_consumer_mappings&.dig(message[:topic])
96
- end
101
+ consumer_obj = if message[:consumer_group]
102
+ _karafka_find_consumer_for_message(message)
103
+ elsif defined?(@consumer)
104
+ @consumer
105
+ else
106
+ _karafka_find_consumer_for_message(message)
107
+ end
97
108
  # Consumer needs to be defined in order to pass messages to it
98
109
  return unless defined?(consumer_obj)
99
110
  # We're interested in adding message to consumer only when it is a Karafka consumer
@@ -103,6 +114,9 @@ module Karafka
103
114
  # We target to the consumer only messages that were produced to it, since specs may also
104
115
  # produce other messages targeting other topics
105
116
  return unless message[:topic] == consumer_obj.topic.name
117
+ # If consumer_group is explicitly specified, verify it matches
118
+ return if message[:consumer_group] &&
119
+ message[:consumer_group].to_s != consumer_obj.topic.consumer_group.name
106
120
 
107
121
  # Build message metadata and copy any metadata that would come from the message
108
122
  metadata = _karafka_message_metadata_defaults(consumer_obj)
@@ -137,21 +151,30 @@ module Karafka
137
151
 
138
152
  # Produces message with a given payload to the consumer matching topic
139
153
  # @param payload [String] payload we want to dispatch
140
- # @param metadata [Hash] any metadata we want to dispatch alongside the payload
154
+ # @param metadata [Hash] any metadata we want to dispatch alongside the payload.
155
+ # Supports an `offset` key to set a custom offset for the message (otherwise
156
+ # offsets auto-increment from 0).
141
157
  def _karafka_produce(payload, metadata = {})
158
+ # Extract offset before passing to WaterDrop since it is not a valid
159
+ # WaterDrop message attribute (Kafka assigns offsets, not producers)
160
+ @_karafka_next_offset = metadata.delete(:offset)
161
+
142
162
  topic = if metadata[:topic]
143
- metadata[:topic]
144
- elsif defined?(@consumer)
145
- @consumer.topic.name
146
- else
147
- @_karafka_consumer_mappings&.keys&.last
148
- end
163
+ metadata[:topic]
164
+ elsif defined?(@consumer)
165
+ @consumer.topic.name
166
+ else
167
+ last_consumer = @_karafka_consumer_mappings&.values&.last
168
+ last_consumer&.topic&.name
169
+ end
149
170
  Karafka.producer.produce_sync(
150
171
  {
151
172
  topic: topic,
152
173
  payload: payload
153
174
  }.merge(metadata)
154
175
  )
176
+ ensure
177
+ @_karafka_next_offset = nil
155
178
  end
156
179
 
157
180
  # @return [Array<Hash>] messages that were produced
@@ -165,8 +188,52 @@ module Karafka
165
188
  @_karafka_consumer_messages
166
189
  end
167
190
 
191
+ # Produces message to a specific consumer instance
192
+ # Use when testing multiple consumers for the same topic
193
+ #
194
+ # @param consumer_instance [Object] the consumer to produce to
195
+ # @param payload [String] message content (usually serialized JSON) to deliver to the
196
+ # consumer
197
+ # @param metadata [Hash] any metadata to dispatch alongside the payload
198
+ #
199
+ # @example Produce to specific consumer when multiple exist for same topic
200
+ # consumer1 = @karafka.consumer_for(:events, :analytics_group)
201
+ # consumer2 = @karafka.consumer_for(:events, :notifications_group)
202
+ # @karafka.produce_to(consumer1, { 'event' => 'click' }.to_json)
203
+ def _karafka_produce_to(consumer_instance, payload, metadata = {})
204
+ _karafka_produce(
205
+ payload,
206
+ metadata.merge(
207
+ topic: consumer_instance.topic.name,
208
+ consumer_group: consumer_instance.topic.consumer_group.name
209
+ )
210
+ )
211
+ end
212
+
168
213
  private
169
214
 
215
+ # Finds a consumer for the given message with backward-compatible fallback
216
+ # @param message [Hash] the message being routed
217
+ # @return [Object, nil] the consumer instance or nil
218
+ def _karafka_find_consumer_for_message(message)
219
+ return nil unless @_karafka_consumer_mappings
220
+
221
+ topic_name = message[:topic]
222
+ consumer_group = message[:consumer_group]
223
+
224
+ if consumer_group
225
+ # Explicit consumer group - find by composite key pattern
226
+ @_karafka_consumer_mappings.values.find do |c|
227
+ c.topic.name == topic_name && c.topic.consumer_group.name == consumer_group.to_s
228
+ end
229
+ else
230
+ # No consumer group specified - find all consumers for this topic
231
+ matching = @_karafka_consumer_mappings.values.select { |c| c.topic.name == topic_name }
232
+ # If exactly one consumer matches, use it (backward compatible)
233
+ (matching.size == 1) ? matching.first : nil
234
+ end
235
+ end
236
+
170
237
  # @param consumer_obj [Karafka::BaseConsumer] consumer reference
171
238
  # @return [Hash] message default options
172
239
  def _karafka_message_metadata_defaults(consumer_obj)
@@ -175,7 +242,7 @@ module Karafka
175
242
  timestamp: Time.now,
176
243
  raw_headers: {},
177
244
  raw_key: nil,
178
- offset: @_karafka_consumer_messages.size,
245
+ offset: @_karafka_next_offset.nil? ? @_karafka_consumer_messages.size : @_karafka_next_offset,
179
246
  partition: 0,
180
247
  received_at: Time.now,
181
248
  topic: consumer_obj.topic.name
@@ -200,10 +267,10 @@ module Karafka
200
267
  @consumer.coordinator = coordinators.find_or_create(topic.name, 0)
201
268
  @consumer.coordinator.seek_offset = 0
202
269
  # Indicate usage as for tests no direct enqueuing happens
203
- @consumer.instance_variable_set('@used', true)
270
+ @consumer.instance_variable_set(:@used, true)
204
271
  expansions = processing_cfg.expansions_selector.find(topic)
205
272
  expansions.each { |expansion| @consumer.singleton_class.include(expansion) }
206
- @_karafka_consumer_mappings[topic.name] = @consumer
273
+ @_karafka_consumer_mappings[topic.id] = @consumer
207
274
  @consumer
208
275
  end
209
276
  end
@@ -11,14 +11,19 @@ module Karafka
11
11
  @minitest_example = minitest_example
12
12
  end
13
13
 
14
- # @param args Anything that the `#_karafka_consumer_for` accepts
15
- def consumer_for(*args)
16
- @minitest_example._karafka_consumer_for(*args)
14
+ # Forwards all arguments to `#_karafka_consumer_for`
15
+ def consumer_for(*)
16
+ @minitest_example._karafka_consumer_for(*)
17
17
  end
18
18
 
19
- # @param args Anything that `#_karafka_produce` accepts
20
- def produce(*args)
21
- @minitest_example._karafka_produce(*args)
19
+ # Forwards all arguments to `#_karafka_produce`
20
+ def produce(*)
21
+ @minitest_example._karafka_produce(*)
22
+ end
23
+
24
+ # Forwards all arguments to `#_karafka_produce_to`
25
+ def produce_to(*)
26
+ @minitest_example._karafka_produce_to(*)
22
27
  end
23
28
 
24
29
  # @return [Array<Hash>] messages produced via `Karafka#producer`