gpt4 book ai didi

ruby-on-rails - 为什么 rspec 从类似的控制台操作中得到不同的结果? (M. Hartl Ruby on Rails 教程 2ed - 第 6.3.4 节)

转载 作者:行者123 更新时间:2023-12-02 01:58:47 28 4
gpt4 key购买 nike

我在 M. Hartl 的 Rails 教程第 6.3.4 节末尾的用户模型 RSpec 测试中遇到问题。我完全迷路了,请帮忙。

除了我需要帮助的一项之外,所有的测试都通过了:

我的问题:为什么 rspec 从类似的控制台操作中得到不同的结果,我该如何解决这个问题并通过测试?

Failures:

1) User return value of authenticate method with valid password

Failure/Error: it { should == found_user.authenticate(@user.password) } expected: User id: 1, name: "Example User", email: "user@example.com", created_at: "2013-08-21 21:38:32", updated_at: "2013-08-21 21:38:32", password_digest: "$2a$04$tjcti4yEYFuJbbz9sa.Z9.F/KXJtHU3A8onU1Fhovn3x..."> got: #User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil, password_digest: "$2a$04$6fdtfzgCFYetjShfYKuFIObWo4Uru4xRMkhW7Ow92O.2...">

Finished in 0.64049 seconds 20 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:100 # User return value of authenticate method with valid password

当我在 Rails 控制台中手动测试它时,验证方法返回完全相同的用户,所有字段都匹配。以下是我的控制台实验:

Loading development environment in sandbox (Rails 4.0.0) Any modifications you make will be rolled back on exit irb(main):001:0>

user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar")

=> #

irb(main):002:0> user.save
(0.3ms) SAVEPOINT active_record_1 User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('user@example.com') LIMIT 1 Binary data inserted for string type on column password_digest

SQL (48.2ms) INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Wed, 21 Aug 2013 21:45:13 UTC +00:00], ["email", "user@example.com"], ["name", "Example User"], ["password_digest", "$2a$10$6tJCohmi7t3OShf/55S5Se98JWvGhJfC1wNAZsc8B6WPP1Zgee0wu"], ["updated_at", Wed, 21 Aug 2013 21:45:13 UTC +00:00]]

(0.2ms)RELEASE SAVEPOINT active_record_1 => true

irb(main):003:0> found_user = User.find_by_email(user.email)

User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'user@example.com' LIMIT 1 => #

irb(main):004:0> user == found_user.authenticate(user.password)

=> true

这是我在 spec/models/user_spec.rb 中的内容

require 'spec_helper'

describe User do

before { @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") }

subject { @user }
.
.
.

describe "return value of authenticate method" do
before { @user.save }
let(:found_user) { User.find_by_email(@user.email) }

describe "with valid password" do
it { should == found_user.authenticate(@user.password) }
end

describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }

it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end

.
.
.
end

用户模型如下

class User < ActiveRecord::Base

before_save { |user| user.email = email.downcase }

validates :name, presence: true, length: { maximum: 50 }

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }

has_secure_password
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true

end

不确定 gem 是否重要,这是我的:

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0'

group :development do
gem 'annotate', '~> 2.4.1.beta'
end

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

# Bootstrap css framework from Twitter
gem 'bootstrap-sass', '2.0.0'

# RSpec testing framework
gem 'rspec-rails', '2.11.0'
gem 'capybara', '2.1.0'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'

group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end

# Use ActiveModel has_secure_password
gem 'bcrypt-ruby', '3.0.1'

提前致谢,如果我遗漏了任何其他重要信息,请告诉我。

最佳答案

您遇到的直接问题是如何设置测试。主题被设置为对象的未保存实例。如果您要在 @user.save 之后执行 before { subject.reload } 那么它会解决这个问题。那真的只是一个创可贴。

真正的问题是您过度复杂化您的规范。您在三个不同的地方以三种不同的方式在三种不同的状态下设置同一用户。这永远不应该发生。

我是这样设置的:

require 'spec_helper'

describe User do
describe "#authenticate" do
let(:user) { User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar") }

it "has a valid password" do
user.authenticate("foobar").should be_true
end

it "has invalid password" do
user.authenticate("invalid").should be_false
end
end
end

请牢记一些注意事项。

创建尽可能少的对象:您创建的对象越多,就越有可能不需要或处于不良状态并且您的测试失败,或者更糟糕的是您的测试很脆弱并且意外失败。

单行 it 很好,但有限制: 当您需要进行一些快速验证时,单行 it block 非常好,但是您应该谨慎使用它们。如果你发现你在 describe 中包装了一个 it block ,那么去掉那个 describe

保持简单:尽量不要预先加载您的测试。当您进行前端加载时,您很可能正在编写符合数据的测试。

http://betterspecs.org/ 上还有很多其他很棒的提示.绝不将此视为法律,但它确实提供了一些很好的信息,可以为编写规范奠定良好的基础。

最后,祝您好运并享受编写规范的乐趣!

关于ruby-on-rails - 为什么 rspec 从类似的控制台操作中得到不同的结果? (M. Hartl Ruby on Rails 教程 2ed - 第 6.3.4 节),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18369467/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com