RSpec 和 Rails 3 - 简单测试失败
RSpec 2.5,Rails 3.0.6 - git://github.com/stevecastaneda/project.git
我正在做一些简单的测试,以确保用户在注册时有效。失败的测试是“应该需要用户名”。产生的错误是:
Failure/Error: new_user(:username => '').should have(1).error_on(:username)
expected 1 error on :username, got 0
user_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe User do
def new_user(attributes = {})
attributes[:username] ||= 'foo'
attributes[:email] ||= '[email protected]'
attributes[:password] ||= 'abc123'
attributes[:password_confirmation] ||= attributes[:password]
User.new(attributes)
end
before(:each) do
User.delete_all
end
it "should be valid" do
new_user.should be_valid
end
it "should require username" do
new_user(:username => '').should have(1).error_on(:username)
end
end
User.rb
class User < ActiveRecord::Base
# new columns need to be added here to be writable through mass assignment
attr_accessible :username, :email, :password, :password_confirmation
attr_accessor :password
before_save :prepare_password
validates_presence_of :username
validates_uniqueness_of :username, :email, :allow_blank => true
validates_format_of :username, :with => /^[-\w\._@]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@"
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_presence_of :password, :on => :create
validates_confirmation_of :password
validates_length_of :password, :minimum => 4, :allow_blank => true
# login can be either username or email address
def self.authenticate(login, pass)
user = find_by_username(login) || find_by_email(login)
return user if user && user.password_hash == user.encrypt_password(pass)
end
def encrypt_password(pass)
BCrypt::Engine.hash_secret(pass, password_salt)
end
private
def prepare_password
unless password.blank?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = encrypt_password(password)
end
end
end
正如你所看到的,我只是创建一个新用户(还没有使用工厂,只是简单的测试)空用户名,并且由于 validates_presence_of :username
它应该有错误。
我缺少什么?
RSpec 2.5, Rails 3.0.6 - git://github.com/stevecastaneda/project.git
I'm doing a few simple tests to make sure users are valid when registering. The test that is failing is "should require username". The resulting error is:
Failure/Error: new_user(:username => '').should have(1).error_on(:username)
expected 1 error on :username, got 0
user_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe User do
def new_user(attributes = {})
attributes[:username] ||= 'foo'
attributes[:email] ||= '[email protected]'
attributes[:password] ||= 'abc123'
attributes[:password_confirmation] ||= attributes[:password]
User.new(attributes)
end
before(:each) do
User.delete_all
end
it "should be valid" do
new_user.should be_valid
end
it "should require username" do
new_user(:username => '').should have(1).error_on(:username)
end
end
User.rb
class User < ActiveRecord::Base
# new columns need to be added here to be writable through mass assignment
attr_accessible :username, :email, :password, :password_confirmation
attr_accessor :password
before_save :prepare_password
validates_presence_of :username
validates_uniqueness_of :username, :email, :allow_blank => true
validates_format_of :username, :with => /^[-\w\._@]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@"
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_presence_of :password, :on => :create
validates_confirmation_of :password
validates_length_of :password, :minimum => 4, :allow_blank => true
# login can be either username or email address
def self.authenticate(login, pass)
user = find_by_username(login) || find_by_email(login)
return user if user && user.password_hash == user.encrypt_password(pass)
end
def encrypt_password(pass)
BCrypt::Engine.hash_secret(pass, password_salt)
end
private
def prepare_password
unless password.blank?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = encrypt_password(password)
end
end
end
As you can see I'm simply creating a new user (not using factories just yet, just simple tests) with an empty username and because of validates_presence_of :username
it should have errors.
What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于您使用 Mocha 作为您的模拟框架,因此您需要告诉 Rspec(仅将 Mocha 放入您的
Gemfile
中是不够的)。在您的spec_helper.rb
文件中,将其更改为:
,然后所有测试都会通过。
更多信息:
如果您单独运行它,您的
User
模型规范实际上工作得很好:您的
UsersController
规范实际上是干扰者,这就是为什么为整个项目运行rspec
失败的原因。您的控制器规格先于模型规格运行。在您的控制器规范中,您有几个
User.any_instance.stub...
调用。您的最后一个UsersController
规范存根valid?
为 true。这些不仅仅适用于您的控制器规格。一旦您达到了User
模型规范,对valid?
的调用仍然会因为此存根而返回 true,因为 Rspec 不知道您正在使用 Mocha。Since you're using Mocha for your mock framework, you need to tell Rspec this (just putting Mocha in your
Gemfile
won't be enough). In yourspec_helper.rb
file, change this:To this:
and all of your tests will pass.
More Info:
Your
User
model spec is actually working perfectly fine, if you run it by itself:Your
UsersController
spec is actually the one interfering, which is why runningrspec
for your entire project fails.Your controller specs run before your model specs. In your controller specs, you have a couple
User.any_instance.stub...
calls. Your very lastUsersController
spec stubsvalid?
to be true. These are not scoped only for your controller specs. Once you hit yourUser
model spec, calls tovalid?
still return true because of this stubbing, since Rspec doesn't know you're using Mocha.您需要添加
否则,不会执行验证,因此不会出现错误。
对我有用:
将其更改
为:
You need to add
Otherwise the validation is not performed, and, therefor, there're no errors.
Works for me:
Change this:
to this:
实际上,罪魁祸首是您的 users_controller_spec,该行是:
The culprit, actually, is your users_controller_spec, and the line is: