Ich bin neu in Mock-Objekten, und ich versuche zu lernen, wie man sie in RSpec verwendet. Kann jemand bitte ein Beispiel (ein Hallo RSpec Mock-Objekt Welttyp Beispiel) oder einen Link (oder eine andere Referenz) zur Verwendung der RSpec-Mock-Objekt-API posten?RSpec Mock Object Beispiel
Antwort
Hier ist ein Beispiel für eine einfache mock ich für einen Controller-Test in einer Rails-Anwendung haben:
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
In diesem Fall bin ich spöttisch die Seite & Pagetype-Modelle (Objekte) sowie Anstoßen aus ein paar der Methoden, die ich anrufe.
Das mir die Möglichkeit gibt, einen Test wie dies auszuführen:
it "should be successful" do
Page.should_receive(:find_by_id).and_return(@page)
get 'show', :id => 1
response.should be_success
end
Ich weiß, diese Antwort mehr Schienen spezifisch ist, aber ich hoffe, es hilft Ihnen heraus ein wenig.
bearbeiten
Ok, hier so ein Hallo Welt Beispiel ...
mit dem folgenden Skript (hello.rb):
class Hello
def say
"hello world"
end
end
Wir schaffen können die folgende Spezifikation (hallo_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
Ich habe nicht genug Punkte, um einen Kommentar zu einer Antwort zu posten, aber ich wollte sagen, dass die akzeptierte Antwort mir auch dabei half herauszufinden, wie man einen zufälligen Wert eingibt.
Ich musste in der Lage sein, eine Objektinstanzwert Stummel, die zufällig zum Beispiel zugeordnet:
class ClumsyPlayer < Player do
def initialize(name, health = 100)
super(name, health)
@health_boost = rand(1..10)
end
end
Da ist in meinem spec ich herauszufinden, hatte ein Problem, wie die ungeschickte Spielers zufällige Gesundheit Stummel zu testen Wenn sie eine Heilung bekommen, bekommen sie den richtigen Schub für ihre Gesundheit.
Der Trick war:
@player.stub!(health_boost: 5)
Damit stub!
war der Schlüssel, ich hatte stub
gerade mit und wurde noch zufällig rspec Pässe und Ausfälle bekommen.
Also danke Brian
Strom (3.x) RSpec bietet sowohl reine Mock-Objekte (wie in tokhi's answer) und teilweise spöttisch (Anrufe auf ein vorhandenes Objekt spöttisch). Hier ist ein Beispiel für eine teilweise Verspottung. Es verwendet expect
und receive
, um einen Order
Aufruf an eine CreditCardService
zu verspotten, so dass der Test nur besteht, wenn der Anruf getätigt wird, ohne es tatsächlich zu machen.
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
In diesem Beispiel ist die mock auf dem Rückgabewert von CreditCardService.instance
ist, die vermutlich ein Singleton ist.
with
ist optional; ohne sie würde jeder Anruf zu refund
die Erwartung erfüllen. Ein Rückgabewert könnte mit and_return
gegeben werden; In diesem Beispiel wird es nicht verwendet, daher gibt der Aufruf nil
zurück.
In diesem Beispiel wird RSpec aktuelle (expect .to receive
) spöttische Syntax, die mit einem Objekt arbeitet. Die akzeptierte Antwort verwendet die alte Methode rspec-rails mock_model
, die für ActiveModel-Modelle spezifisch war und aus rspec-rails in ein anderes Juwel verschoben wurde.
mock
ist basierend auf diesem Github pull veraltet.
Anstatt nun können wir double
verwenden - mehr here...
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
Dank für das Beispiel, es deff. half – agentbanks217
Sie erstellen ein Mock-Objekt der Klasse, die Sie spekulieren/testen sollen, was bedeutet, dass Sie die Klasse, die überhaupt entwickelt wird, nicht ausüben. Zwecklos. Mocking soll Ihnen helfen, die getestete Klasse/System mit Objekten zu umgeben, die sich glaubwürdig als reale Welt darstellen, wenn auch einfacher/kontrolliert/in sich abgeschlossen. Es ist ein Anti-Pattern, um Mocking zu verwenden, um interne Funktionen der entwickelten Klasse zu überprüfen. –
Diese Antwort ist nicht mehr aktuell. Siehe [tokhis Antwort unten] (https://stackoverflow.com/a/39573538/634576) für das Schreiben eines reinen Mock-Objekts und [meine] (https://Stackoverflow.com/a/39186152/634576) für wie im aktuellen RSpec teilweise verspotten. –