ruby - 根据生成的随机数在 Rspec 中测试随机天气方法功能
问题描述
我正在尝试进行 2 次测试来检查Weather
类中方法的功能。该random_weather
方法应@status
根据random_number
. 但是我找不到强制random_number
成为某个数字的方法。
RSpec 测试:
require 'weather'
describe Weather do
subject { Weather.new }
it 'Can create an instance of Weather' do
expect(subject).to be_instance_of Weather
end
it 'Can return sunny when randomly choosing weather' do
subject.stub(:generate_random_number) {5}
expect(subject.status).to eq "Sunny"
end
it 'Can return stormy when randomly choosing weather' do
subject.stub(:generate_random_number) {9}
expect(subject.status).to eq "Stormy"
end
end
天气等级:
class Weather
attr_reader :status, :random_number
def initialize
@random_number = generate_random_number
puts @random_number
if (1..8).include?(@random_number)
@status = "Sunny"
else
@status = "Stormy"
end
end
def generate_random_number
rand(1..10)
end
end
失败示例:
1) Weather Can return stormy when randomly choosing weather
Failure/Error: expect(subject.status).to eq "Stormy"
expected: "Stormy"
got: "Sunny"
(compared using ==)
# ./spec/weather_spec.rb:17:in `block (2 levels) in <top (required)>'
解决方案
您有 3 个选项:
- 在方法中包装随机性并存根此方法
- 包装或注入的生成器类,并在规范中注入非随机生成器
- 存根
rand
我更喜欢第二种选择,但第一种可能就足够了。
私有方法
class Weather
attr_reader :status, :random_number
def random_weather
@random_number = generate_random_number
# ...
end
def generate_random_number
rand(1..10)
end
end
#specs
it 'Can return sunny when randomly choosing weather' do
subject.stub(:generate_random_number) {5}
expect(subject.status).to eq "Sunny"
end
发电机注入
class Weather
attr_reader :status, :random_number
def initialize(random_number_generator: RandomNumberGenerator)
@random_number_generator = random_number_generator
end
def random_weather
@random_number = random_number_generator.call
# ...
end
end
class RandomNumberGenerator
def self.call
rand(1..10)
end
end
#specs
subject { described_class.new(generator) }
let(:generator) { ->{ 5 } }
it 'Can return sunny when randomly choosing weather' do
expect(subject.status).to eq "Sunny"
end
rand
规范中的存根
it 'Can return sunny when randomly choosing weather' do
stub(:rand) {5}
expect(subject.status).to eq "Sunny"
end