首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异常异常RSpec

异常异常RSpec
EN

Stack Overflow用户
提问于 2017-09-03 17:40:49
回答 1查看 126关注 0票数 0

我有一个方法depart(plane),它接受一个错误fail "The plane can't set off because it is stormy" if @weather.stormy?。这是我的airport class中定义的

代码语言:javascript
复制
class Airport

  attr_accessor :planes, :landed, :weather

  def initialize(weather = Weather.new)
    #plane has no location when initialized

    @landed = nil
    @planes  = []
    @weather = weather

  end


  def land(plane)
    fail "You can't land this plane again!" if @landed == true
    @planes << plane
    @landed = true
  end

  def depart(plane)

    fail "The plane has already departed" if @landed == false
    fail "The plane can't set off because it is stormy" if @weather.stormy?
    @planes.pop
    puts "Your plane has left the airport!"
    @landed = false
    end
  end

我还有一班飞机:

代码语言:javascript
复制
class Plane
end

方法.stormy?是一种产生随机数的方法。如果这个数字高于75,就会产生风暴,否则它就是假的。这是我的weather class中定义的

代码语言:javascript
复制
def stormy?
    number > 70 ? true : false
end

def number
    rand(1..100)
end

我正在尝试使用fail "The plane can't set off because it is stormy" if @weather.stormy?测试错误RSpec。我发现这非常困难,因为我对RSpec非常陌生。

我遇到的问题是通过这个测试,因为风暴可能是对的,也可能是假的。我如何预置一个值并测试它?

我的整个airport_spec.rb文件:

代码语言:javascript
复制
require 'airport'
require 'plane'
require 'weather'

describe Airport do

  let(:airport) { Airport.new }
  let(:plane) { double :plane }
  let(:weather) { double :weather}
  #let(:weather) {double :weather}

  it 'creates new airports' do
    expect(:airport).to eq(:airport)
  end

  it 'accepts landed planes' do
    subject.land(:plane)
    expect(subject.landed).to be(true)
  end

 describe '#initialize' do
  it 'initializes a planes array when airport is instantiated' do
    expect(airport.planes).to be_an_instance_of(Array)
  end

  it 'initializes the plane to be landed to be nil upon instantiation' do
    expect(airport.landed).to be nil
  end

  it 'instantiates a new weather object upon initialization' do
    weather = airport.weather
    expect(airport.weather).to eq weather
  end
end

 describe '#land' do
   it 'adds a plane to the planes array when landed' do
    subject.land(:plane)
    expect(subject.planes).to eq [:plane]
  end

  it 'will not land a plane that is already landed' do

    subject.land(:plane)
    expect {subject.land(:plane)}.to raise_error("You can't land this plane again!")
  end
end

  describe '#depart' do

  it 'will not allow a plane to take off when it is stormy' do
   weather = Weather.new
   allow(weather).to receive(:stormy?).and_return true
   expect{subject.depart(plane)}.to raise_error("The plane can't set off because it is stormy")
   end
end

  describe '#full' do
    it 'will raise an error when the airport is too full' do
    expect(subject.full?).to eq(true)
    end
  end
end

正在失败的测试:

代码语言:javascript
复制
    it 'will not allow a plane to take off when it is stormy' do
        weather = Weather.new
        allow(Airport.new).to receive(weather.stormy?).and_return true
        expect{subject.depart(plane)}.to raise_error("The plane can't set off because it is stormy")
    end
end

为什么我要:

代码语言:javascript
复制
Failures:

  1) Airport#depart will not allow a plane to take off when it is stormy
     Failure/Error: expect{subject.depart(plane)}.to raise_error("The plane can't set off because it is stormy")
       expected Exception with "The plane can't set off because it is stormy" but nothing was raised
     # ./spec/airport_spec.rb:75:in `block (3 levels) in <top (required)>'

Finished in 0.02878 seconds (files took 0.15908 seconds to load)
12 examples, 1 failure

RSpec version : 3.5.4

另一次我跑:

代码语言:javascript
复制
Failures:

  1) Airport#depart will not allow a plane to take off when it is stormy
     Failure/Error: expect{subject.depart(plane)}.to raise_error("The plane can't set off because it is stormy")
       expected Exception with "The plane can't set off because it is stormy" but nothing was raised
     # ./spec/airport_spec.rb:58:in `block (3 levels) in <top (required)>'

  2) Airport#depart removes a plane from the planes array when taken-off
     Failure/Error: fail "The plane can't set off because it is stormy" if @weather.stormy?

     RuntimeError:
       The plane can't set off because it is stormy
     # ./lib/airport.rb:20:in `depart'
     # ./spec/airport_spec.rb:63:in `block (3 levels) in <top (required)>'

Finished in 0.03361 seconds (files took 0.15734 seconds to load)
16 examples, 2 failures

Failed examples:

rspec ./spec/airport_spec.rb:56 # Airport#depart will not allow a plane to take off when it is stormy
rspec ./spec/airport_spec.rb:61 # Airport#depart removes a plane from the planes array when taken-off

然而,有时它可以工作并通过:

代码语言:javascript
复制
COVERAGE: 100.00% -- 76/76 lines in 6 files

Benjamins-MacBook-Pro:airport_challenge benjamin$ rspec

Airport
  creates new airports
  accepts landed planes
  #initialize
    initializes a planes array when airport is instantiated
    initializes the plane to be landed to be nil upon instantiation
    instantiates a new weather object upon initialization
  #land
    adds a plane to the planes array when landed
    will not land a plane that is already landed
  #depart
    will not allow a plane to take off when it is stormy
  #full
    will raise an error when the airport is too full

Plane
  creates new planes

Weather
  creates a weather object
  #number
    will create a random number
  #storm
    will either be stormy or sunny

Have you considered running rubocop? It will help you improve your code!
Try it now! Just run: rubocop

Finished in 0.01254 seconds (files took 0.15439 seconds to load)
13 examples, 0 failures


COVERAGE:  96.05% -- 73/76 lines in 6 files

+----------+----------------+-------+--------+---------+
| coverage | file           | lines | missed | missing |
+----------+----------------+-------+--------+---------+
|  83.33%  | lib/airport.rb | 18    | 3      | 25-27   |
+----------+----------------+-------+--------+---------+
5 file(s) with 100% coverage not shown
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-03 18:14:16

当您说allow(Airport.new).to receive...时,这是在设置一个新的Airport,而不是指您使用let设置的那个。

stormy?方法在Weather上,因此期望应该是:

代码语言:javascript
复制
allow(weather).to receive(:stormy?).and_return true

并设置测试主题,使用模拟的stormy?方法使用天气:

代码语言:javascript
复制
let(:weather) { double :weather }
subject { Airport.new(weather) }

作为附加解释,receive采用了将被调用的方法的名称。编写receive(weather.stormy?)时,RSpec试图将来自weather.stormy?的返回值(即TrueFalse)转换为用作方法名称的符号,因此undefined method to _sym‘’。

查看您的规范的完整版本,您目前是一个隐式主题,即基于describe Airport... RSpec创建了一个使用Airport.new (没有参数)作为规范主题的Airport。这意味着主题没有使用weather对象,因为您已经在使用stormy?方法,因此仍然在使用真正的stormy?方法。这就是为什么我使用subject { Airport.new(weather) }设置一个显式主题的原因。最后,您不希望在测试中设置本地weather (weather = Weather.new),因为您希望allow(weather)...引用来自传递给测试对象的let的天气。

下面是规范的完整版本以及所做的更改:

代码语言:javascript
复制
require 'airport'

describe Airport do

  let(:weather) { double :weather }
  subject { Airport.new(weather) }
  let(:plane) { double :plane }

    it 'will not allow a plane to take off when it is stormy' do
      allow(weather).to receive(:stormy?).and_return true
      expect { subject.depart(plane) }.to raise_error("The plane can't set off because it is stormy")
    end

end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46026166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档