应用程序工作,但在rSpec测试失败

时间:2011-12-27 17:33:12

标签: ruby-on-rails rspec

在用户模型中,我有以下方法:

  def generate_and_set_new_password!
    password = random_pronouncable_token
    self.password_hash = encrypt(password)
    self.password_reset_sent_at = Time.now
    if self.save!
      password
    else
      nil
    end
  end

  private

    def encrypt(string)
      # Some code that encrypts string
      # ...
    end

    def random_pronouncable_token(size = 4)
      # Some code that generates new password
      # ...

    end

rSpec测试:

describe "New password generation" do
  it "should generate new password" do
    user = @user
    old_pwd_hash = user.password_hash
    pwd = user.generate_and_set_new_password!
    pwd.should_not be_nil
    user.password_hash.should_not == old_pwd_hash
  end
end

这个测试给了我这样的输出:

  1) User password encryption New password generation should generate new password
     Failure/Error: user.password_hash.should_not == old_pwd_hash
       expected not: == "966abfff742d73c71fc87a1928b90aec"
                got:    "966abfff742d73c71fc87a1928b90aec"

'generate_and_set_new_password! '方法在app中正常工作,这是控制台的示例:

ruby-1.8.7-p249 :014 > user.password_hash
 => "ef10fb44dfceeaca05ca78030c1d8cb5" 
ruby-1.8.7-p249 :015 > user.generate_and_set_new_password!
 => "quispopeho" 
ruby-1.8.7-p249 :016 > user.password_hash
 => "a0b7605d5d6ca2152f7e019b4896fef4" 
ruby-1.8.7-p249 :017 > 

正如我们所看到的,它为用户提供了新的password_hash,因此它可以正常工作。

我认为这是rSpec中的一些错误。我做了这样的实验:

以下是测试代码中的一些更改:

describe "New password generation" do
  it "should generate new password" do
    user = @user
    old_pwd_hash = user.password_hash

    p "old_password = ", user.password
    p "old_pwd_hash = ", old_pwd_hash

    pwd = user.generate_and_set_new_password!
    p "received new password = #{pwd}"
    p "SHOULD BE a new_pwd_hash, but it isn't! ", user.password_hash
    p "SHOULD BE a new_password, but it isn't! ", user.password
    pwd.should_not be_nil
    # There I am tring to set this new password explicitly :)
    user.password = pwd
    user.save
    p "NOW it is other password hash = ", user.password_hash
    user.password_hash.should_not == old_pwd_hash
  end
end

现在测试通过了!

调试输出如下:

"old_password = foobar"
"old_pwd_hash = c251e8a9bcc4fba1199181b1f2c1430c"
"received new password = kongibyty"
"SHOULD BE a new_pwd_hash, but it isn't! c251e8a9bcc4fba1199181b1f2c1430c"
"SHOULD BE a new_password, but it isn't! foobar"
"NOW it is other password hash = e2b53133b796bcb212a0c1fa1d2a1cfa"

正如我从这个调试输出中看到的那样,用户对象只有在测试代码中明确设置后才能获得它的新密码_hash。好像'generate_and_set_new_password!'方法无法更改在测试环境中创建的对象。

为什么我会得到如此奇怪的rSpec行为? 任何建议都会有用。

关于我的发展环境的一些其他信息:

我正在使用:

  ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]
  Rails 3.0.9
  rvm

Gemfile片段:

group :development, :test do
  gem "rspec-rails", "~> 2.6"
  gem 'webrat', '0.7.1'
  gem 'spork', '0.9.0.rc9'
  gem 'autotest-standalone'
  gem 'autotest', '4.4.6'
  gem 'autotest-rails-pure', '4.1.2'
  gem 'factory_girl_rails', '1.0'
end 

Udpates:

创建@user

的代码
require 'spec_helper'

describe User do

  # attributes for user object
  before(:each) do
    @attr = {
      :email => "user@example.com",
      :password => "foobar",
      :password_confirmation => "foobar",
      :first_name => "Example",
      :last_name => "Examploid",
      :dob => Date.new(1980,07,03),
      :relationships_status => "Single",
      :sex => "male",
      :sexual_orientaion => "Woman",
      :about_me => "All about me",
      :school_id => 1,
      :education_id => 1,
      :occupation_id => 1,
      :web_site => "example.com"
    }
  end

  # Some other tests...
  # ...

  describe "password encryption" do

    # create user
    before(:each) do
      @user = User.create!(@attr)
    end

    # Some other tests...
    # ...

    # Here is shown the same test code as above.
    describe "New password generation" do

      it "should generate new password" do

        # I even tried to use factory_girl's method
        # @user = Factory(:device_user)

        user = @user
        old_pwd_hash = user.password_hash

        pwd = user.generate_and_set_new_password!

        pwd.should_not be_nil

        user.password_hash.should_not == old_pwd_hash
      end
    end

  end

end

一些澄清:

我没有在任何测试中使用@ user方法的存根。

我尝试用factory_girl做同样的事情,并且同样的测试失败了。 这里是用户的工厂定义:

Factory.define :device_user, :class => User do |user|
  user.password              "password"
  user.password_confirmation "password"
  user.email                 "device_user@example.com"
  user.first_name            "Device"
  user.last_name             "User"
  user.dob                    Date.new(2011,10,03)
  user.relationships_status  "Single"
  user.sex                   "male"
  user.sexual_orientaion     "Woman"
  user.about_me              "All about Device User"
  user.school_id             1
  user.education_id          1
  user.occupation_id         1
  user.web_site              "device.example.com"
  user.facebook_id           "face_test_id"
end

0 个答案:

没有答案