使用Rspec测试无效的电子邮件

ale*_*nco 5 rspec ruby-on-rails

这来自Learn Rails by example book:

 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
Run Code Online (Sandbox Code Playgroud)

我是Rspec的初学者.以前,有一个这样的代码:

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end
Run Code Online (Sandbox Code Playgroud)

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

 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
Run Code Online (Sandbox Code Playgroud)

好吧,也许这段代码错了.但基本上,我问为什么作者之前没有使用beforeit或者之前放过address变量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
Run Code Online (Sandbox Code Playgroud)

Bra*_*rth 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
Run Code Online (Sandbox Code Playgroud)

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

@user.email = ' '
@user.should_not be_valid
Run Code Online (Sandbox Code Playgroud)

但是第三个块会到达之前循环遍历整个数组it,结果只有:

@user.email = 'foo@bar+baz.com'
@user.should_not be_valid
Run Code Online (Sandbox Code Playgroud)

在最后一个例子中,他正在针对同一个对象执行一系列操作,这些操作在之前进行评估it,只需要运行一次才有意义.

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