rails中的mock和stubs的实际示例

时间:2014-08-11 19:45:37

标签: ruby-on-rails ruby unit-testing rspec

有足够的questions与此主题相关,但没有一个提供practial示例引用差异。

根据 Fowler的文章模拟不是存根,存根是独立于外部调用的假方法,而模拟是假对象,具有对调用的预编程反应。

Stub不能让您的测试失败,但Mocks可以。

  

模拟更具体,与对象相关:如果某些参数是   传递,然后对象返回某些结果。一个人的行为   对象被模仿或被模仿"。

     

Stubbing更通用,与方法相关:通常是一种存根方法   返回所有参数的结果总是相同。一个人的行为   方法是冻结的,罐装的或" stubbed"。

我们采取一个简单的test案例。我们必须找到一个提供了id并与用户相关的Book

  it "can find an Book that this user belongs to" do 
    project = Book.find( id: '22', email: user@test.com )      
    expect(project) to eq(some_data);  
  end

在上面的例子中......什么是存根,什么是模拟?如果我的示例无效,任何人都可以向我显示模拟存根的example

1 个答案:

答案 0 :(得分:1)

让我们举两个例子:

let(:email) { 'email' }

# object created from scratch
let(:mocked_book) { instance_double Book, email: email } 
it 'check mock' do
  expect(mocked_book.email).to eq email
end

# 
let(:book) { Book.new }
it 'check stub' do
  allow(book).to receive(:email) { email }
  expect(book.email).to eq email
end

您的示例不相关:您不会测试有效记录,但您需要stub才能返回mock

假设你需要测试一本书收到的方法,例如:

def destroy
  @book = Book.find(params[:id])
  if @book.destroyable?
    @book.destroy
  else
    flash[:error] = "errr"
  end
  redirect_to books_path
end

您可以使用以下代码进行测试:

it 'is not destroyed if not destroyable' do
  mocked_book = double 'book', destroyable?: false
  allow(Book).to receive(:find).and_return mocked_book
  expect(mocked_book).to_not receive :destroy
  # here goes the code to trigger the controller action
end

it 'is destroyed if destroyable' do
  mocked_book = double 'book', destroyable?: true
  allow(Book).to receive(:find).and_return mocked_book
  expect(mocked_book).to receive :destroy
  # here goes the code to trigger the controller action
end

你可以在这里看到利弊:

  • 缺点:模拟必须确切知道预期的方法是什么

  • 专业人士:使用模拟器,您不需要真正创建对象并将其设置为使其适合某些条件