RSpec模拟对象示例

我是模仿对象的新手,我正在学习如何在RSpec中使用它们。 有人可以发表一个例子(你好RSpec模拟对象的世界types的例子),或链接(或任何其他参考)如何使用RSpec模拟对象的API?

下面是一个简单的模拟例子,我在一个rails应用程序中进行了一个控制器testing:

before(:each) do @page = mock_model(Page) @page.stub!(:path) @page.stub!(:find_by_id) @page_type = mock_model(PageType) @page_type.stub!(:name) @page.stub!(:page_type).and_return(@page_type) end 

在这种情况下,我正在嘲笑Page&PageType模型(对象),并扼杀了我所调用的一些方法。

这使我能够运行这样的testing:

 it "should be successful" do Page.should_receive(:find_by_id).and_return(@page) get 'show', :id => 1 response.should be_success end 

我知道这个答案是更具体的轨道,但我希望它可以帮助你一点。


编辑

好吧,这里是一个你好世界的例子…

鉴于以下脚本(hello.rb):

 class Hello def say "hello world" end end 

我们可以创build下面的规范(hello_spec.rb):

 require 'rubygems' require 'spec' require File.dirname(__FILE__) + '/hello.rb' describe Hello do context "saying hello" do before(:each) do @hello = mock(Hello) @hello.stub!(:say).and_return("hello world") end it "#say should return hello world" do @hello.should_receive(:say).and_return("hello world") answer = @hello.say answer.should match("hello world") end end end 

我没有足够的观点来发表评论,但我想说的是,接受的答案也帮助我试图找出如何在随机值中存根。

我需要能够存根据随机分配的对象的实例值,例如:

 class ClumsyPlayer < Player do def initialize(name, health = 100) super(name, health) @health_boost = rand(1..10) end end 

然后在我的规范中,我想知道如何把笨拙的玩家的随机健康存起来,以便testing当他们得到治疗时,他们的健康得到了适当的提升。

诀窍是:

 @player.stub!(health_boost: 5) 

所以那个stub! 是关键,我只是使用stub ,仍然得到随机rspec通行证和失败。

所以谢谢Brian

mock是基于这个github 拉不推荐。

现在,我们可以使用double – 在这里…

  before(:each) do @page = double("Page") end it "page should return hello world" do allow(@page).to receive(:say).and_return("hello world") answer = @page.say expect(answer).to eq("hello world") end 

下面的例子使用expectreceive来模拟一个OrderCreditCardService的调用,这样testing只有在调用的时候才会通过,而不必真正做出来。

 class Order def cancel CreditCardService.instance.refund transaction_id end end describe Order do describe '#cancel' do it "refunds the money" do order = Order.new order.transaction_id = "transaction_id" expect(CreditCardService.instance).to receive(:refund).with("transaction_id") order.cancel end end end 

在这个例子中,模拟是CreditCardService.instance的返回值,这大概是一个单例。

with是可选的; 没有它,任何refund电话将满足期望。 返回值可以用and_return给出; 在这个例子中它没有被使用,所以调用返回nil


本示例使用RSpec的当前( expect .to receive )模拟语法,该语法适用于任何对象。 接受的答案使用旧的rspec-rails mock_model方法,这是特定于ActiveModel模型,并被移出rspec-rails到另一个gem。