5

这来自通过示例书学习 Rails

 describe "when email format is invalid" do
    it "should be invalid" do
      addresses = %w[user@foo,com user_at_foo.org example.user@foo.
                     foo@bar_baz.com foo@bar+baz.com]
      addresses.each do |invalid_address|
        @user.email = invalid_address
        @user.should_not be_valid
      end      
    end

我是Rspec的初学者。之前有这样一段代码:

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end

所以我想知道为什么作者没有这样写上面的代码:

 describe "when email format is invalid" do
    before do
      addresses = %w[user@foo,com user_at_foo.org example.user@foo.
                     foo@bar_baz.com foo@bar+baz.com]
      @user.email = invalid_address 
      addresses.each do |invalid_address|
        @user.email = invalid_address
      end 
    end

    it { should_not be_valid }          
 end

好的,也许这段代码是错误的。但基本上,我在问为什么作者没有使用beforebeforeit或将address变量放在 before it?(就像他在前面的例子中所做的那样)

编辑:

他还在另一个例子中做了类似的事情:

 describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.email = @user.email.upcase
      user_with_same_email.save
    end

    it { should_not be_valid }
  end
4

1 回答 1

7

答案在于before块实际上在做什么。在这些测试中,它在运行之前已完全it运行。

因此,第一个代码块运行(并且可以编写)为:

@user.email = 'user@foo,com'
@user.should_not be_valid
@user.email = 'user_at_foo.org'
@user.should_not be_valid
@user.email = 'example.user@foo.'
@user.should_not be_valid
@user.email = 'foo@bar_baz.com'
@user.should_not be_valid
@user.email = 'foo@bar+baz.com'
@user.should_not be_valid

第二个代码块运行(并且可以编写)为:

@user.email = ' '
@user.should_not be_valid

但是第三个块会在到达之前遍历整个数组it,只导致:

@user.email = 'foo@bar+baz.com'
@user.should_not be_valid

在最后一个示例中,他正在对同一个对象执行一系列操作,这些操作在 之前进行评估it,只需要运行一次即可。

希望这有帮助,祝你好运!

于 2012-10-27T03:01:07.993 回答