解
感谢史蒂文哈曼的这个要点,我得到了它的工作.devise_mail_helpers.rb
module Features
module MailHelpers
def last_email
ActionMailer::Base.deliveries[0]
end
# Can be used like:
# extract_token_from_email(:reset_password)
def extract_token_from_email(token_name)
mail_body = last_email.body.to_s
mail_body[/#{token_name.to_s}_token=([^"]+)/, 1]
end
end
end
Run Code Online (Sandbox Code Playgroud)
我将文件添加devise_mail_helpers.rb到功能规格所在的文件夹中并编写了此规范.
require 'devise_mail_helpers.rb'
include Features
include MailHelpers
describe "PasswordResets" do
it "emails user when requesting password reset" do
user = FactoryGirl.create(:user)
visit root_url
find("#login_link").click
click_link "Forgot your password?"
fill_in "Email", :with => user.email
click_button "Send instructions"
current_path.should eq('/users/sign_in')
page.should have_content("You will receive an email with instructions about how to …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过使用factorygirl创建用户创建一个注销流程规范,然后使用Devise的sign_in方法对用户进行身份验证,然后使用capybara单击"注销"链接.
当我运行规范时,我得到(在我看来是什么)一个奇怪的错误:
Failures:
1) Sign out flow successfully redirects to the welcome index (root)
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `env' for nil:NilClass
# /home/vagrant/.rvm/gems/ruby-2.0.0-p576/gems/devise-3.4.1/lib/devise/test_helpers.rb:24:in `setup_controller_for_warden'
Finished in 0.00226 seconds (files took 3.32 seconds to load)
1 example, 1 failure
Run Code Online (Sandbox Code Playgroud)
这是规格:
require 'rails_helper'
describe "Sign out flow" do
include Devise::TestHelpers
describe "successfully" do
it "redirects to the welcome index (root)" do
user = create(:user)
sign_in user
within '.user-info' do
click_link 'Sign Out'
end …Run Code Online (Sandbox Code Playgroud) 我正在使用FactoryGirl和Faker在我的seeds.rb文件中生成用户对象但由于某种原因,正在创建完全相同的用户并且rake db:seed由于电子邮件唯一性验证而失败.
用户工厂:
#users.rb
require 'faker'
FactoryGirl.define do
factory :user do
first_name Faker::Name.first_name
last_name Faker::Name.last_name
phone Faker::PhoneNumber.cell_phone
email Faker::Internet.email
password "password"
password_confirmation "password"
end
end
Run Code Online (Sandbox Code Playgroud)
和seeds.rb文件中的代码:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
Run Code Online (Sandbox Code Playgroud)
错误:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
如果我打开控制台并使用FactoryGirl.create(:user)我得到相同的结果......相反的对象正在反复创建,即使我只运行Faker::Internet.email几次我会收到几封电子邮件.
工厂女工:
[1] pry(main)> FactoryGirl.create(:user)
...
=> #<User id: 3, first_name: "Osvaldo", last_name: "Wunsch", email: "willy@damore.net", phone: "(912)530-4949 x64848", created_at: "2014-07-31 20:57:27", updated_at: "2014-07-31 20:57:27", encrypted_password: "$2a$10$mxWC7yLYR0m/Sw8MO6Lyru.xuTHCdCEuM9Orx3LXGApF...", reset_password_token: nil, reset_password_sent_at: …Run Code Online (Sandbox Code Playgroud) 假设我有一个模型user,它对该email字段有唯一性约束
如果我打电话Factory(:user)一切都很好,但是如果我第二次打电话它会因"条目已存在"错误而失败.
我目前正在使用一个简单的帮助程序在创建工厂之前在数据库中搜索现有条目...并调用我通过该帮助程序创建的任何工厂.
它有效,但它并不完全优雅,考虑到我认为这个问题有多常见,我猜这是一个更好的解决方案.那么,工厂女孩是否有一种内置return_or_create的工厂方式,而不仅仅是提前充电create()?如果没有,大多数人如何避免与他们的工厂重复输入?
假设您有以下mongoid文档:
class User
include Mongoid::Document
embeds_one :name
end
class UserName
include Mongoid::Document
field :first
field :last_initial
embedded_in :user
end
Run Code Online (Sandbox Code Playgroud)
你如何创建一个工厂女工厂,初始化嵌入的名字和最后的名字?你也将如何处理这种embeds_many关系呢?
给定两个对象之间的标准has_many关系.举个简单的例子,我们来看看:
class Order < ActiveRecord::Base
has_many :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :order
end
Run Code Online (Sandbox Code Playgroud)
我想要做的是生成带有存根行项目列表的存根订单.
FactoryGirl.define do
factory :line_item do
name 'An Item'
quantity 1
end
end
FactoryGirl.define do
factory :order do
ignore do
line_items_count 1
end
after(:stub) do |order, evaluator|
order.line_items = build_stubbed_list(:line_item, evaluator.line_items_count, :order => order)
end
end
end
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,因为Rails想要在分配line_items时调用order并且FactoryGirl引发异常:
RuntimeError: stubbed models are not allowed to access the database
那么你如何(或者可能)生成一个存根对象,其中has_may集合也是存根的?
我有一个网络服务,为几个不同的客户提供广告.广告的结构因客户端而异,因此,我通过客户名称为我的模型和控制器使用名称空间来区分广告.从高层看,它看起来像这样:
'app/models/client1/ad.rb'
class Client1::Ad < ActiveRecord::Base
attr_accessible :title, :description
end
Run Code Online (Sandbox Code Playgroud)
'app/models/client2/ad.rb'
class Client2::Ad < ActiveRecord::Base
attr_accessible :title, :description, :source
end
Run Code Online (Sandbox Code Playgroud)
实际上,这些模型更复杂并且具有关联性,但这不是重点.
我正在使用rspec-rails 2.4.0和factory_girl_rails 1.0.1编写一些单元测试,并且我的所有工厂都运行良好.但是,我无法为命名空间模型定义工厂.我尝试过类似的东西:
Factory.define :client1_ad, :class => Client1::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
end
Run Code Online (Sandbox Code Playgroud)
和
Factory.define :client2_ad, :class => Client2::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
ad.source "feed"
end
Run Code Online (Sandbox Code Playgroud)
它没有完成这项工作.我环顾四周,但我看到的每个例子都使用非命名空间的模型.有人有主意吗?任何输入都非常感谢.
我正在尝试使用factory_girl创建一个"用户"工厂(使用RSpec)但是它似乎没有在事务上运行,并且由于测试数据库中先前测试的残余数据而显然失败了.
Factory.define :user do |user|
user.name "Joe Blow"
user.email "joe@blow.com"
user.password 'password'
user.password_confirmation 'password'
end
@user = Factory.create(:user)
Run Code Online (Sandbox Code Playgroud)
运行第一组测试很好:
spec spec/
...
Finished in 2.758806 seconds
60 examples, 0 failures, 11 pending
Run Code Online (Sandbox Code Playgroud)
一切都很好并且符合预期,但是再次运行测试:
spec spec/
...
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:1102:in `save_without_dirty!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/dirty.rb:87:in `save_without_transactions!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:182:in `transaction'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/proxy/create.rb:6:in `result'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/factory.rb:316:in `run'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/factory.rb:260:in `create'
from /Users/petenixey/Rails_apps/resample/spec/controllers/users_controller_spec.rb:7
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:183:in …Run Code Online (Sandbox Code Playgroud) 我在模型中有一个方法:
class Article < ActiveRecord::Base
def do_something
end
end
Run Code Online (Sandbox Code Playgroud)
我还对此方法进行了单元测试:
# spec/models/article_spec.rb
describe "#do_something" do
@article = FactoryGirl.create(:article)
it "should work as expected" do
@article.do_something
expect(@article).to have_something
end
# ...several other examples for different cases
end
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到我发现将此方法转移到after_save回调中更好:
class Article < ActiveRecord::Base
after_save :do_something
def do_something
end
end
Run Code Online (Sandbox Code Playgroud)
现在我对这个方法的所有测试都破了.我必须解决它:
do_something因为create或save将触发此方法,或者我将遇到重复的数据库操作.create到build使用general model.save而不是单独的方法调用model.do_something
describe "#do_something" do
@article = FactoryGirl.build(:article)
it "should work as expected" do
expect{@article.save}.not_to raise_error …Run Code Online (Sandbox Code Playgroud)activerecord rspec ruby-on-rails ruby-on-rails-3 factory-bot
transient doFactoryBot工厂的目的是什么?
我见过很多以下面的东西开头的工厂.
factory :car do
owner nil
other_attribute nil
end
...
Run Code Online (Sandbox Code Playgroud)
我在这个博客上找到了一些信息:http://blog.thefrontiergroup.com.au/2014/12/using-factory-easily-create-complex-data-sets-rails/
但我仍然不完全明白如何以及为什么这样做.我对FactoryBot的体验很小.
任何有使用FactoryBot经验的人都可以分享一些见解吗?
factory-bot ×10
rspec ×4
devise ×2
activerecord ×1
capybara ×1
database ×1
embed ×1
faker ×1
fixtures ×1
mongoid ×1
namespaces ×1
rspec2 ×1
ruby ×1
seeding ×1