从另一个类ruby调用方法

时间:2016-04-16 21:22:03

标签: ruby rspec

我刚开始使用Ruby和Rspec,所以如果我不是非常具体,我会提前为我的错误语法道歉。

我有两个班级,机场和天气,应该沟通,所以我可以在机场的天气中调用stormy?方法。我想做的是在天气恶劣时停止飞机起飞。 我已经定义了bad_weather方法,但它不起作用 这是我的代码:

我在Rspec的考试

describe Airport do 
  it ' does not allow planes to take off with stormy weather' do
    subject.take_off double(:plane)
    expect {(weather).to be_stormy?}.to raise_error "Flight cancelled due to bad weather"
  end
end

我想从

获取方法的课程
class Weather

  def stormy?
   roll >= 6
  end

private

  def roll
    rand(10)
  end
end

我要在

中调用该方法
class Airport

   DEFAULT_CAPACITY = 10

   def initialize
     @planes = []
     @capacity = DEFAULT_CAPACITY
   end


  def take_off(plane)
    fail "Flight cancelled due to bad weather" if bad_weather?
    @planes.pop
  end

  def bad_weather?
    weather = Weather.new
    weather.stormy?
  end
end

我知道我的Rspec测试很糟糕,任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:3)

当您遇到被测对象依赖其他对象的情况时,您希望控制这些对象。在您的方案中,您希望控制weather知道的airport

为了做到这一点,你需要强制它,当你问stormy?它时,它会返回true。这样你就可以确保你对Airport类进行单元测试,并且所有对其他对象的依赖都在控制之中。

我将如何做到这一点:

class Airport
   DEFAULT_CAPACITY = 10

   def initialize
     @planes = []
     @capacity = DEFAULT_CAPACITY
   end

  def take_off(plane)
    fail "Flight cancelled due to bad weather" if bad_weather?
    @planes.pop
  end

  def bad_weather?
    weather.stormy?
  end

  def weather
    @weather ||= Weather.new
  end
end

然后在您的测试中,您将通过这样做控制您的机场weather

it 'does not allow planes to take off with stormy weather' do
  my_airport = Airport.new
  stormy_weather = Weather.new
  allow(stormy_weather).to receive(:is_stormy?) { true }
  allow(my_airport).to receive(:weather) { stormy_weather }

  expect(my_airport.take_off("Boeing")).to raise_error "Flight cancelled due to bad weather"
end

@SteveTurczyn答案也有效。我个人不喜欢它,因为你不只是让机场的天气暴风雨,而是任何Weather实例。

答案 1 :(得分:0)

测试此方法的技巧是强制#stormy?为真,然后测试take_off方法调用是否会引发错误。

it 'does not allow planes to take off with stormy weather' do
  allow_any_instance_of(Weather).to receive(:stormy?).and_return(true)
  my_airport = Airport.new
  expect(my_airport.take_off("Boeing")).to raise_error "Flight cancelled due to bad weather"
end

顺便提一下,您还要测试条件的反函数,因此另一项测试将非常有用。

it 'does not complain about bad weather if weather is good' do
  allow_any_instance_of(Weather).to receive(:stormy?).and_return(false)
  my_airport = Airport.new
  expect(my_airport.take_off("Boeing")).not_to raise_error "Flight cancelled due to bad weather"
end