在编写rspec测试用例时如何覆盖ruby方法的局部变量?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在编写rspec测试用例时如何覆盖ruby方法的局部变量?相关的知识,希望对你有一定的参考价值。
现有的Ruby代码:
def book_details
book_count = Book.count
while (book_count > 1)
# Do something
end
end
我想写一个rspec测试用例,它在book_details函数中设置book_count值。可能吗?如果有,怎么样?
到目前为止,我所尝试的是:
it 'Should return 1 book details only' do
allow(Model).to receive(book_count).and_return(1)
# Do something
end
但是这给#错误'未定义的局部变量或方法`book_count'#
答案
让我们说book_count = 1000是在ruby代码中你想用rspec将它重置为10,然后下面就可以了:
allow(Book).to receive(:count).and_return(10)
以上将根据您对rspec的期望进行计数。
另外,特别是你的rspec contexts
,rspec
是为methods
而不是local variables
。所以,在rspec
测试方法的期望。
下面是你的rspec
的简单method
示例:
class Book
def book_details
book_count = Book.count
while (book_count > 1)
puts 'Book name'
end
end
end
describe 'Books' do
describe '#book_details' do
context 'when Books are less than one' do
it 'should not return book details' do
book_details.should eq 0
book_details.should_not eq 'Book name'
end
end
context 'when Books are more than one' do
before do
FactoryGirl.create(:book)
end
it 'should return book details' do
book_details.should_not eq 0
book_details.should eq 'Book name'
end
end
end
end
另一答案
答案基本上是:不要。
如果您觉得需要在方法中间覆盖变量,那么您做错了;该方法责任太多,需要分解。
在这种情况下,让测试工作的一种快速方法是:
allow(Book).to receive(:count).once.and_return(1)
或者,稍微更简洁的方法是将该调用提取到一个新方法中,因此您只是将您“拥有”的行为存根 - 例如:
class Foo
def book_details
while (book_count > 1)
# Do something
end
end
def book_count
Book.count
end
end
# In your test:
let(:foo) { Foo.new }
allow(foo).to receive(:book_count).once.and_return(1)
......但事实上,你应该在这里做的事情,理想情况下,正确地测试方法,就是不要嘲笑任何东西!由于您的代码与数据库交互,因此您的测试应该为要与之交互的代码创建真实记录:
# Using FactoryBot, for example:
let!(:books) { create_list(:book, 5) }
另一答案
Book.stub(:count).and_return(10)
以上是关于在编写rspec测试用例时如何覆盖ruby方法的局部变量?的主要内容,如果未能解决你的问题,请参考以下文章