Suppose I have the following code.
class Answer
enum type: %i[text checkbox image]
def round_type
case answer.type
when text, checkbox
:text
when image
:multimedia
else
raise 'Unknown type'
end
end
end
require 'rails_helper'
RSpec.describe Answer, type: :model do
describe '#round_type' do
context 'when type is text' do
it 'returns text' do
# omitted
end
end
context 'when type is checkbox' do
it 'returns text' do
end
end
context 'when type is image' do
it 'returns multimedia' do
end
end
end
end
Then I add video type to the enum. And I expect the method returns multimedia when the type is video.
But the round_type method and the test codes are not support video type. So I will finally realize it when I get an error in production.
I'd like to know what I have to change the method before the error occurs.
So, this is my question: How can I detect the timing when I have to change a method in rspec?
CodePudding user response:
If I understood you correctly, you have to make your specs a bit more dynamic and you have to test the else
statement as well:
class Answer
enum type: %i[text checkbox image]
def round_type
case type
when 'text', 'checkbox'
:text
when 'image'
:multimedia
else
raise 'Unknown type'
end
end
end
RSpec.describe Answer, type: :model do
describe '#round_type' do
it 'raises error for unknown type' do
# empty `type` is an unknown type in this situation
expect { Answer.new.round_type }.to raise_error
end
it 'does not raise error for available types' do
# NOTE: loop through all types and check that `round_type` method
# recognizes each one.
Answer.types.each_key do |key|
expect { Answer.new(type: key).round_type }.to_not raise_error
end
end
end
end
Next time you add a new type
and forget to update round_type
method, the last spec will fail.
https://relishapp.com/rspec/rspec-expectations/v/3-11/docs/built-in-matchers/raise-error-matcher