在编写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 contextsrspec是为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方法的局部变量?的主要内容,如果未能解决你的问题,请参考以下文章

在使用 Jasmine Karma 编写测试用例时,我无法涵盖正在执行的处理程序

编写测试用例时弱变量变为空?

当生产功能可能有数百万个测试用例时,TDD 是如何工作的?

ICloneable 的 C# 测试用例

如何使用rspec编写测试用例来发送通知消息

逻辑覆盖