5

これは、サンプルブックによるLearnRailsからのものです。

 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

OK、多分このコードは間違っています。beforeしかし、基本的に、著者が以前に使用しなかったのか、変数を以前にit配置しなかったのかを尋ねています。(前の例で行ったように)addressit

編集:

彼はまた、さらなる例で同様のことをします:

 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

そして、コードの2番目のブロックは次のように実行されます(そして書くことができます):

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

ただし、3番目のブロックは、に到達するに配列全体をループするため、次itの結果になります。

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

最後の例では、彼は同じオブジェクトに対して一連の操作を実行しています。これらの操作は、の前に評価されます。これは、it意味をなすために1回だけ実行する必要があります。

これがお役に立てば幸いです。

于 2012-10-27T03:01:07.993 に答える