Rspec:期望与带块的期望 - 有什么区别? [英] Rspec: expect vs expect with block - what's the difference?

查看:45
本文介绍了Rspec:期望与带块的期望 - 有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

刚刚学习 rspec 语法,我注意到这段代码有效:

Just learning rspec syntax and I noticed that this code works:

  context "given a bad list of players" do
    let(:bad_players) { {} }

    it "fails to create given a bad player list" do
       expect{ Team.new("Random", bad_players) }.to raise_error
     end 
  end

但是这段代码没有:

  context "given a bad list of players" do
    let(:bad_players) { {} }

    it "fails to create given a bad player list" do
       expect( Team.new("Random", bad_players) ).to raise_error
     end 
  end

它给了我这个错误:

Team given a bad list of players fails to create given a bad player list
     Failure/Error: expect( Team.new("Random", bad_players) ).to raise_error
     Exception:
       Exception
     # ./lib/team.rb:6:in `initialize'
     # ./spec/team_spec.rb:23:in `new'
     # ./spec/team_spec.rb:23:in `block (3 levels) in <top (required)>'

我的问题是:

  1. 为什么会发生这种情况?
  2. 在 ruby​​ 中,前面和后面的例子有什么区别?

我也在寻找规则何时使用另一个

I am also looking for rules on when to use one over the other

另一个相同但相反结果的示例,此代码有效:

One more example of the same but inverse results, where this code works:

  it "has a list of players" do
    expect(Team.new("Random").players).to be_kind_of Array
  end 

但是这段代码失败了

  it "has a list of players" do
    expect{ Team.new("Random").players }.to be_kind_of Array
  end

在这种情况下我得到的错误是:

Error I get in this case is:

Failure/Error: expect{ Team.new("Random").players }.to be_kind_of Array
       expected #<Proc:0x007fbbbab29580@/Users/amiterandole/Documents/current/ruby_sandbox/tdd-ruby/spec/team_spec.rb:9> to be a kind of Array
     # ./spec/team_spec.rb:9:in `block (2 levels) in <top (required)>'

我正在测试的类看起来像这样:

The class I am testing looks like this:

class Team
  attr_reader :name, :players

  def initialize(name, players = [])
    raise Exception unless players.is_a? Array

    @name = name
    @players = players
  end
end

推荐答案

如前所述:

expect(4).to eq(4)

这是专门测试您作为参数发送给方法的值.当您尝试在执行相同操作时测试引发的错误时:

This is specifically testing the value that you've sent in as the parameter to the method. When you're trying to test for raised errors when you do the same thing:

expect(raise "fail!").to raise_error

您的参数会立即被评估,并且该异常将被抛出并且您的测试将在那里爆炸.

Your argument is evaluated immediately and that exception will be thrown and your test will blow up right there.

但是,当您使用块(这是基本的 ruby​​)时,块内容不会立即执行 - 它的执行由您调用的方法决定(在这种情况下,expect 方法处理何时执行您的块):

However, when you use a block (and this is basic ruby), the block contents isn't executed immediately - it's execution is determined by the method you're calling (in this case, the expect method handles when to execute your block):

expect{raise "fail!"}.to raise_error

我们可以看一个可能处理这种行为的示例方法:

We can look at an example method that might handle this behavior:

def expect(val=nil)
  if block_given?
    begin
      yield
    rescue
      puts "Your block raised an error!"
    end
  else
    puts "The value under test is #{val}"
  end
end

您可以在这里看到 expect 方法正在手动挽救您的错误,以便它可以测试是否引发错误等.yield 是一个红宝石方法执行传递给方法的任何块的方式.

You can see here that it's the expect method that is manually rescuing your error so that it can test whether or not errors are raised, etc. yield is a ruby method's way of executing whatever block was passed to the method.

这篇关于Rspec:期望与带块的期望 - 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆