gpt4 book ai didi

ruby-on-rails - 为什么factory_girl无法为我进行交易? -测试后行保留在数据库中

转载 作者:行者123 更新时间:2023-12-03 08:14:31 24 4
gpt4 key购买 nike

我正在尝试使用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)

运行第一组测试就可以了:
spec spec/ 


...
Finished in 2.758806 seconds

60 examples, 0 failures, 11 pending

一切正常,符合预期,但是再次运行测试:
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 `module_eval'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:183:in `subclass'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:55:in `describe'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_factory.rb:31:in `create_example_group'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/dsl/main.rb:28:in `describe'
from /Users/petenixey/Rails_apps/resample/spec/controllers/users_controller_spec.rb:3
from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:147:in `load_without_new_constant_marking'
from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:147:in `load'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:15:in `load_files'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `each'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/options.rb:133:in `run_examples'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/command_line.rb:9:in `run'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/bin/spec:5
from /usr/bin/spec:19:in `load'
from /usr/bin/spec:19

修复尝试-使用Factory.sequence

由于我的电子邮件字段具有唯一性约束,因此我尝试使用factory_girl的sequence方法解决此问题:
Factory.define :user do |user|
user.name "Joe Blow"
user.sequence(:email) {|n| "joe#{n}@blow.com" }
user.password 'password'
user.password_confirmation 'password'
end

然后我跑了
rake db:test:prepare
spec spec/
.. # running the tests once executes fine
spec spec/
.. # running them the second time produces the same set of errors as before

用户似乎保留在数据库

如果我查看/db/test.sqlite3数据库,似乎在两次测试之间没有从数据库回退测试用户的行。我认为这些测试应该是事务性的,但对我而言似乎并非如此。

这可以解释为什么测试第一次正确运行(如果我清除数据库),但是第二次失败。

谁能解释一下我应该做些什么以确保测试能够以事务方式运行?

最佳答案

终于解决了这个问题,希望我可以节省一个人六个小时的调试工作,这使我得以解决。

通过a)幸运并得到一个可以正常工作的代码版本,以及b)剥离两组代码,这就是我发现的结果:

测试会阻塞

require 'spec_helper'

describe UsersController do

@user = Factory.create(:user)
end

测试有效
require 'spec_helper'

describe UsersController do

it "should make a factory models without choking" do
@user = Factory.create(:user)
end
end

事务是由 定义的,它“应该做某事”执行... 语句。如果您在该语句之外实例化工厂,则表明它不是事务性的。

您也可以将其放在“它应该..”块之外,只要它位于“before..end”块中即可。
require 'spec_helper'

describe UsersController do

before(:each) do
@user = Factory.create(:user)
end

it 'should make a factory without choking' do
puts @user.name
# prints out the correnct name for the user
end
end

在实验中,在“它应该做..end”块之外定义用户似乎是有效的,只要它在“之前..end”块中即可。我猜这只能在“它应该做..end”块的范围内执行,因此可以正常工作。

[感谢@jdl的建议(也是正确的)]

关于ruby-on-rails - 为什么factory_girl无法为我进行交易? -测试后行保留在数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3497135/

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