我看了一些tutes,我看到的只是关于如何测试before_create的旧帖子。此外,似乎他们只是测试before_create被称为即:。
@user = User.new
@user.should_receive(:method_name_called_by_before_create)
@user.send(:before_create) (sometimes they just do @user.save)
我想实际测试我的方法是否有效,并且在创建记录后已经分配(并保存了变量)。
以下是我的模特:
user.rb
class User < ActiveRecord::Base
has_one :character, :dependent => :destroy
after_create :generate_character
private
def generate_character
self.create_character(:name => "#{email}'s avatar")
end
end
和character.rb
class Character < ActiveRecord::Base
belongs_to :user
before_create :generate_character
private
def generate_character
response = api_call
#API CALL HERE
#set object attributes here
self.stat1 = calculate_stat1(response) + 5
self.stat2 = calculate_stat2(response) + 5
self.stat3 = calculate_stat3(response) + 5
end
def api_call
return api_call_response
end
end
我想测试生成角色确实设置属性而不上线并调用API调用。这对rspec有可能吗?我有一个json响应的夹具,所以我希望我可以生成字符然后使用假响应进行测试。
这是我的character.spec:
describe Character do
before(:each) do
Character.any_instance.stub!(:api_call).and_return(fake_response.read)
@user = Factory(:user)
@character = @user.character
puts @character.inspect
end
def fake_response
File.open("spec/fixtures/api_response.json")
end
每个角色的统计数据只打印出5个。我还在character.rb的generate_character方法中做了一个puts response
,它仍然打印出“真正的”api调用。
我设法做了一个放入fake_response并且它确实经过那里,但它也经过了“真正的”api_call之后,这使得存根过时了。我如何度过难关?
答案 0 :(得分:4)
这里的一个好方法是将api调用解压缩为自包含方法。像这样:
class Character < ActiveRecord::Base
belongs_to :user
before_create :generate_character
private
def generate_character
data = api_call
#set object attributes from data
end
def api_call
# returns a data structure
# resulting from the call
end
end
然后使用RSpec的any_instance来存根api_call方法以返回固定的数据结构
Character.any_instance.stub!(:api_call).and_return { {:id => 1, :attribute_one => "foo"} }
@user = User.create
@user.character.attribute_one.should == "foo"
有关any_instance check this commit
的更多信息