fea*_*ool 6 ruby datamapper factory-bot
这个简单的例子使用DataMapper的before :save回调(aka hook)来递增callback_count.callback_count初始化为0,并应由回调设置为1.
通过以下方式创建TestObject时,将调用此回调:
TestObject.create()
Run Code Online (Sandbox Code Playgroud)
但是当FactoryGirl通过以下方式创建时会跳过回调:
FactoryGirl.create(:test_object)
Run Code Online (Sandbox Code Playgroud)
知道为什么吗?[注意:我正在运行ruby 1.9.3,factory_girl 4.2.0,data_mapper 1.2.0]
详细信息如下......
# file: models/test_model.rb
class TestModel
include DataMapper::Resource
property :id, Serial
property :callback_count, Integer, :default => 0
before :save do
self.callback_count += 1
end
end
Run Code Online (Sandbox Code Playgroud)
# file: spec/factories.rb
FactoryGirl.define do
factory :test_model do
end
end
Run Code Online (Sandbox Code Playgroud)
# file: spec/models/test_model_spec.rb
require 'spec_helper'
describe "TestModel Model" do
it 'calls before :save using TestModel.create' do
test_model = TestModel.create
test_model.callback_count.should == 1
end
it 'fails to call before :save using FactoryGirl.create' do
test_model = FactoryGirl.create(:test_model)
test_model.callback_count.should == 1
end
end
Run Code Online (Sandbox Code Playgroud)
Failures:
1) TestModel Model fails to call before :save using FactoryGirl.create
Failure/Error: test_model.callback_count.should == 1
expected: 1
got: 0 (using ==)
# ./spec/models/test_model_spec.rb:10:in `block (2 levels) in <top (required)>'
Finished in 0.00534 seconds
2 examples, 1 failure
Run Code Online (Sandbox Code Playgroud)
解决了。
@Jim Stewart 向我指出了这个 FactoryGirl 问题,其中写着“FactoryGirl 在[它创建的]实例上调用 save!”。在 DataMapper 的世界中,save!明确不运行回调——这解释了我所看到的行为。(但它并没有解释为什么它适用于@enthrops!)
该链接还提供了一些专门针对 DataMapper 的解决方法,我可能会选择其中之一。不过,如果未修改的 FactoryGirl 能够与 DataMapper 配合良好,那就太好了。
这是由thoughtbot 的Joshua Clayton 建议的代码。我将其添加到我的spec/factories.rb文件中,test_model_spec.rb现在顺利通过。凉豆子。
# file: factories.rb
class CreateForDataMapper
def initialize
@default_strategy = FactoryGirl::Strategy::Create.new
end
delegate :association, to: :@default_strategy
def result(evaluation)
evaluation.singleton_class.send :define_method, :create do |instance|
instance.save ||
raise(instance.errors.send(:errors).map{|attr,errors| "- #{attr}: #{errors}" }.join("\n"))
end
@default_strategy.result(evaluation)
end
end
FactoryGirl.register_strategy(:create, CreateForDataMapper)
Run Code Online (Sandbox Code Playgroud)
出色地。也许我说得太早了。添加 CreateForDataMapper 可以修复一项特定测试,但似乎会破坏其他测试。所以我暂时不回答我的问题。还有人有好的解决办法吗?
| 归档时间: |
|
| 查看次数: |
2729 次 |
| 最近记录: |