Ruby 使用rspec创建后的测试
我的模型中有代码Ruby 使用rspec创建后的测试,ruby,ruby-on-rails-3,rspec,rspec2,rspec-rails,Ruby,Ruby On Rails 3,Rspec,Rspec2,Rspec Rails,我的模型中有代码 class Foo < ActiveRecord::Base after_create :create_node_for_foo def create_node_for_user FooBar.create(id: self.id) end end 但是我的测试失败了 Failures: 1) Foo create node in graph database on Failure/Error: FooBar.should_
class Foo < ActiveRecord::Base
after_create :create_node_for_foo
def create_node_for_user
FooBar.create(id: self.id)
end
end
但是我的测试失败了
Failures:
1) Foo create node in graph database on
Failure/Error: FooBar.should_receive(:create).with(id: foo1.id)
(<FooBar (class)>).create({:id=>18})
expected: 1 time
received: 0 times
可能出了什么问题?好的,我们解决了这个问题 改变了这个
it "create node in graph database" do
foo1 = FactoryGirl.create(:foo)
FooBar.should_receive(:create).with(id: foo1.id)
end
到
好吧,我有问题了 改变了这个
it "create node in graph database" do
foo1 = FactoryGirl.create(:foo)
FooBar.should_receive(:create).with(id: foo1.id)
end
到
晚会有点晚了,但事实上,上述方法行不通。您可以创建自定义匹配器来执行此操作:
class EventualValueMatcher
def initialize(&block)
@block = block
end
def ==(value)
@block.call == value
end
end
def eventual_value(&block)
EventualValueMatcher.new(&block)
end
然后在您的规范中执行以下操作:
it "create node in graph database" do
foo1 = FactoryGirl.build(:foo)
FooBar.should_receive(:create).with(eventual_value { { id: foo1.id } })
foo1.save
end
这意味着模拟将在事实发生之后才对块进行评估,并且它实际上已经被设置好了。对聚会来说有点晚,但实际上上面的方法不起作用。您可以创建自定义匹配器来执行此操作:
class EventualValueMatcher
def initialize(&block)
@block = block
end
def ==(value)
@block.call == value
end
end
def eventual_value(&block)
EventualValueMatcher.new(&block)
end
然后在您的规范中执行以下操作:
it "create node in graph database" do
foo1 = FactoryGirl.build(:foo)
FooBar.should_receive(:create).with(eventual_value { { id: foo1.id } })
foo1.save
end
这意味着模拟将在事实发生后才对块进行评估,并且它实际上已被设置。如果它对某人有所帮助,则Dan Draper解决方案的更新版本将与块一起使用自定义匹配器,如下所示: 规格/支持/最终值匹配器.rb RSpec::Matchers.define:最终的_值do |预期| 匹配do |实际值| 实际==预期的.call 终止 终止 使用方法: require support/finally_value_matcher,或者您可以在rails_helper.rb文件中执行全局require 它是xxx做的 foo1=FactoryGirl.build:foo expectFooBar.to receive:create.WithEvalueProc{foo1.id} 救命! 终止
如果对某人有帮助,Dan Draper解决方案的更新版本将使用带有块的自定义匹配器,如下所示: 规格/支持/最终值匹配器.rb RSpec::Matchers.define:最终的_值do |预期| 匹配do |实际值| 实际==预期的.call 终止 终止 使用方法: require support/finally_value_matcher,或者您可以在rails_helper.rb文件中执行全局require 它是xxx做的 foo1=FactoryGirl.build:foo expectFooBar.to receive:create.WithEvalueProc{foo1.id} 救命! 终止
为什么这改变了什么?我重构了我的一个测试,就像你做的一样,但它仍然不起作用。你知道为什么和/或RSpec在幕后做什么吗?这与RSpec在幕后无关,只是简单的逻辑。在他更改它之前,问题是.create在.should测试之前被调用。更改后,.build用于生成记录,请记住,此时记录尚未创建。然后他打电话来。保存以实际创建记录。这就是为什么它会起作用,为什么它会改变什么?我重构了我的一个测试,就像你做的一样,但它仍然不起作用。你知道为什么和/或RSpec在幕后做什么吗?这与RSpec在幕后无关,只是简单的逻辑。在他更改它之前,问题是.create在.should测试之前被调用。更改后,.build用于生成记录,请记住,此时记录尚未创建。然后他打电话来。保存以实际创建记录。这就是它起作用的原因。