require './spec/spec_helper'
require './bank'
describe Bank do
context "#transfer" do
before(:all) do
@customer1 = Customer.new(500)
customer2 = Customer.new(0)
@customer1.stub(:my_money).and_return(1000)
customer2.stub(:my_money).and_return(0)
@transfer_message = Bank.new.transfer(@customer1, customer2, 2000)
end
it "should return insufficient balance if transferred amount is greater than balance" do
expect(@transfer_message).to eq("Insufficient funds")
end
it "calls my_money" do
expect(@customer1).to have_received(:my_money)
end
end
end
当我使用before(:each)
代替before(:all)
时,它有效。但是如果使用before(:all)
,它会将错误抛出为undefined method proxy_for for nil:NilClass
。我找不出原因。请你帮助我好吗?提前谢谢。
答案 0 :(得分:8)
before(:all)
,但不支持在before(:all)
中使用来自rspec-mocks的双精度数。有关背景,请参阅github issue中引用的问题。
当前master
版本的rspec-mocks将与3.0.0.beta2一起使用,将失败,并显示以下错误:
The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
以前的版本会在存根时生成undefined method proxy_for ...
错误。
答案 1 :(得分:7)
晚会?是的,但是我不介意从我发现的东西中减去一分钱。我在尝试在RSpec.configure
块中存根请求时遇到了类似的错误,因此存根仅对我传递config.around(:each, option)
选项的示例可用。
因此,这意味着我在RSpec::Mocks
here不支持的个别示例范围之外使用存根!解决方法是在上下文中使用临时范围。
所以你有
before(:all) do
RSpec::Mocks.with_temporary_scope do
@customer1 = Customer.new(500)
customer2 = Customer.new(0)
@customer1.stub(:my_money).and_return(1000)
customer2.stub(:my_money).and_return(0)
@transfer_message = Bank.new.transfer(@customer1, customer2, 2000)
end
end
HTH!
答案 2 :(得分:5)
这应该有效:
require "rspec/mocks/standalone"
before(:all) do
答案 3 :(得分:0)
我不确定使用@El'Magnifico's answer是否像RSpec::Mocks.with_temporary_scope
一样规范/最佳实践,但是我发现通过使用around
钩子而不是before
,我能够向before
中动态注入example_group
块(和类似的块),从而使它们与我的测试一起运行:
# spec/spec_helper.rb
RSpec.configure do |config|
# ..snip..
config.include RequestForgerySpecHelper, type: :feature
# ..snip..
end
# spec/support/request_forgery_spec_helper.rb
module RequestForgerySpecHelper
def self.included(base)
base.around(:all) do |ex|
puts "around all start"
ex.example_group.prepend_before do
puts "around all inside prepend_before"
end
ex.example_group.append_after do
puts "around all inside append_after"
end
ex.run
puts "around all end"
end
end
end
现在,如果我们假设测试已经打印了一些日志before
,after
,并且在test
本身内部,则输出如下所示:
around all start
around all inside prepend_before
inside spec file before
inside spec file test
inside spec file after
around all inside append_after
around all end
由于我们现在正在将before
钩子动态注入到与测试相同的上下文中,因此我们不再看到以下错误:
before
在示例内(例如it
块)或在示例范围内运行的构造(例如before
,let
,等等)。它仅在示例组(例如describe
或context
块)上可用
提供给ex
钩子的around
参数是RSpec::Core::Example::Procsy
的一个实例,它通过RSpec::Core::Example
属性提供对example
实例的访问。 / p>
RSpec::Core::Example
使我们可以通过example_group
方法访问与此测试关联的RSpec::Core::ExampleGroup
。
RSpec::Core::ExampleGroup
使我们能够访问DSL /方法,从而使我们能够动态定义before
/ after
/ let
/ etc块,而不会触发not available from within an example
错误;如我们在pry中列出的方法所见:
ls RSpec::Core::ExampleGroup
# RSpec::Core::Hooks#methods: after append_after append_before around before hooks prepend_after prepend_before
# RSpec::Core::MemoizedHelpers::ClassMethods#methods: let let! subject subject!
# RSpec::Core::ExampleGroup.methods:
# add_example currently_executing_a_context_hook? define_nested_shared_group_method describe ensure_example_groups_are_configured fcontext ffeature fit fspecify include_examples location parent_groups run scenario specify superclass_metadata update_inherited_metadata xexample xspecify
# before_context_ivars declaration_locations delegate_to_metadata described_class example fdescribe file_path focus id it metadata pending run_after_context_hooks set_it_up store_before_context_ivars top_level? with_replaced_metadata xfeature
# children define_example_group_method descendant_filtered_examples description example_group feature filtered_examples for_filtered_examples idempotently_define_singleton_method it_behaves_like next_runnable_index_for remove_example run_before_context_hooks set_ivars subclass top_level_description xcontext xit
# context define_example_method descendants each_instance_variable_for_example examples fexample find_and_eval_shared fscenario include_context it_should_behave_like ordering_strategy reset_memoized run_examples skip superclass_before_context_ivars traverse_tree_until xdescribe xscenario