1+ Feature : `have_reported_error` matcher
2+
3+ The `have_reported_error` matcher is used to check if an error was reported
4+ to Rails error reporting system (`Rails.error`). It can match against error
5+ classes, instances, messages, and attributes.
6+
7+ The matcher supports several matching strategies:
8+ * Any error reported
9+ * Specific error class
10+ * Specific error instance with message
11+ * Error message patterns using regular expressions
12+ * Error attributes using `.with()`
13+ * Symbol errors
14+
15+ The matcher is available in all spec types where Rails error reporting is used.
16+
17+ Background :
18+ Given a file named "app/models/user.rb" with:
19+ """ruby
20+ class User < ApplicationRecord
21+ def self.process_data
22+ Rails.error.report(StandardError.new("Processing failed"))
23+ end
24+
25+ def self.process_with_context
26+ Rails.error.report(ArgumentError.new("Invalid input"), context: "user_processing", severity: "high")
27+ end
28+
29+ def self.process_custom_error
30+ Rails.error.report(ValidationError.new("Email is invalid"))
31+ end
32+ end
33+ """
34+ And a file named "app/errors/validation_error.rb" with:
35+ """ruby
36+ class ValidationError < StandardError
37+ end
38+ """
39+
40+ Scenario : Checking for any error being reported
41+ Given a file named "spec/models/user_spec.rb" with:
42+ """ruby
43+ require "rails_helper"
44+
45+ RSpec.describe User do
46+ it "reports an error during processing" do
47+ expect {
48+ User.process_data
49+ }.to have_reported_error
50+ end
51+ end
52+ """
53+ When I run `rspec spec/models/user_spec.rb`
54+ Then the examples should all pass
55+
56+ Scenario : Checking for specific error class
57+ Given a file named "spec/models/user_spec.rb" with:
58+ """ruby
59+ require "rails_helper"
60+
61+ RSpec.describe User do
62+ it "reports a StandardError" do
63+ expect {
64+ User.process_data
65+ }.to have_reported_error(StandardError)
66+ end
67+
68+ it "reports an ArgumentError" do
69+ expect {
70+ User.process_with_context
71+ }.to have_reported_error(ArgumentError)
72+ end
73+ end
74+ """
75+ When I run `rspec spec/models/user_spec.rb`
76+ Then the examples should all pass
77+
78+ Scenario : Checking for specific error instance with message
79+ Given a file named "spec/models/user_spec.rb" with:
80+ """ruby
81+ require "rails_helper"
82+
83+ RSpec.describe User do
84+ it "reports error with specific message" do
85+ expect {
86+ User.process_data
87+ }.to have_reported_error(StandardError.new("Processing failed"))
88+ end
89+
90+ it "reports ArgumentError with specific message" do
91+ expect {
92+ User.process_with_context
93+ }.to have_reported_error(ArgumentError.new("Invalid input"))
94+ end
95+ end
96+ """
97+ When I run `rspec spec/models/user_spec.rb`
98+ Then the examples should all pass
99+
100+ Scenario : Checking error message patterns with regular expressions
101+ Given a file named "spec/models/user_spec.rb" with:
102+ """ruby
103+ require "rails_helper"
104+
105+ RSpec.describe User do
106+ it "reports error with message matching pattern" do
107+ expect {
108+ User.process_data
109+ }.to have_reported_error(/Processing/)
110+ end
111+
112+ it "reports error with message containing 'failed'" do
113+ expect {
114+ User.process_data
115+ }.to have_reported_error(/failed$/)
116+ end
117+ end
118+ """
119+ When I run `rspec spec/models/user_spec.rb`
120+ Then the examples should all pass
121+
122+ Scenario : Checking error attributes using `with`
123+ Given a file named "spec/models/user_spec.rb" with:
124+ """ruby
125+ require "rails_helper"
126+
127+ RSpec.describe User do
128+ it "reports error with specific context" do
129+ expect {
130+ User.process_with_context
131+ }.to have_reported_error.with(context: "user_processing")
132+ end
133+
134+ it "reports error with multiple attributes" do
135+ expect {
136+ User.process_with_context
137+ }.to have_reported_error(ArgumentError).with(context: "user_processing", severity: "high")
138+ end
139+ end
140+ """
141+ When I run `rspec spec/models/user_spec.rb`
142+ Then the examples should all pass
143+
144+ Scenario : Checking custom error classes
145+ Given a file named "spec/models/user_spec.rb" with:
146+ """ruby
147+ require "rails_helper"
148+
149+ RSpec.describe User do
150+ it "reports a ValidationError" do
151+ expect {
152+ User.process_custom_error
153+ }.to have_reported_error(ValidationError)
154+ end
155+
156+ it "reports ValidationError with specific message" do
157+ expect {
158+ User.process_custom_error
159+ }.to have_reported_error(ValidationError.new("Email is invalid"))
160+ end
161+ end
162+ """
163+ When I run `rspec spec/models/user_spec.rb`
164+ Then the examples should all pass
165+
166+ Scenario : Using negation - expecting no errors
167+ Given a file named "spec/models/user_spec.rb" with:
168+ """ruby
169+ require "rails_helper"
170+
171+ RSpec.describe User do
172+ it "does not report any errors for safe operations" do
173+ expect {
174+ # Safe operation that doesn't report errors
175+ "safe code"
176+ }.not_to have_reported_error
177+ end
178+ end
179+ """
180+ When I run `rspec spec/models/user_spec.rb`
181+ Then the examples should all pass
182+
183+ Scenario : Using in controller specs
184+ Given a file named "spec/controllers/users_controller_spec.rb" with:
185+ """ruby
186+ require "rails_helper"
187+
188+ RSpec.describe UsersController, type: :controller do
189+ describe "POST #create" do
190+ it "reports validation errors" do
191+ expect {
192+ post :create, params: { user: { email: "invalid" } }
193+ }.to have_reported_error(ValidationError)
194+ end
195+ end
196+ end
197+ """
198+ When I run `rspec spec/controllers/users_controller_spec.rb`
199+ Then the examples should all pass
200+
201+ Scenario : Using in request specs
202+ Given a file named "spec/requests/users_spec.rb" with:
203+ """ruby
204+ require "rails_helper"
205+
206+ RSpec.describe "Users", type: :request do
207+ describe "POST /users" do
208+ it "reports processing errors" do
209+ expect {
210+ post "/users", params: { user: { name: "Test" } }
211+ }.to have_reported_error.with(context: "user_creation")
212+ end
213+ end
214+ end
215+ """
216+ When I run `rspec spec/requests/users_spec.rb`
217+ Then the examples should all pass
218+
219+ Scenario : Complex error matching with multiple conditions
220+ Given a file named "spec/models/user_spec.rb" with:
221+ """ruby
222+ require "rails_helper"
223+
224+ RSpec.describe User do
225+ it "reports error with class, message pattern, and attributes" do
226+ expect {
227+ Rails.error.report(
228+ ArgumentError.new("Invalid user data provided"),
229+ context: "validation",
230+ severity: "critical",
231+ user_id: 123
232+ )
233+ }.to have_reported_error(ArgumentError)
234+ .with(context: "validation", severity: "critical")
235+ end
236+ end
237+ """
238+ When I run `rspec spec/models/user_spec.rb`
239+ Then the examples should all pass
0 commit comments