2016-04-05 7 views
-1

Ich bin ein Neuling in Schienen und ich versuche jetzt, meinen Controller-Code mit Stubbs und Mocks zu testen. Ich versuchte mit dem Code zu spielen, aber ich konnte es nicht richtig machen. Bitte helfen Sie mir mit dem richtigen Code, der refaktoriert wird. Bitte helfen Sie mir mit der Erklärung für den Code, den Sie schreiben.Refactor-Code mit Mock und Stubb

require 'rails_helper' 

RSpec.describe ArticlesController, type: :controller do 
    let(:article) { create :article} 
    let(:art_params) { attributes_for(:article) } 
    let(:dbl) {double(:articles)} 
    describe 'GET index' do 
    it 'assigns @articles' do 
     get :index 
     allow(dbl).to receive(:articles).and_return article 
     expect(dbl.articles).to eql(article) 
     #expect_any_instance_of(Article).to receive(:save).and_return(true) 
    end 

    it 'renders the index template' do 
     get :index 
     allow(dbl).to receive(:articles) 
     expect(response).to render_template('index') 
    end 
    end 

    describe 'GET :new' do 
    it 'render new template' do 
     get :new 
     expect(response).to render_template(:new) 
    end 
    end 

    describe 'POST/create' do 
    it 'created a new article ' do 
    expect { post :create, article: art_params }.to change(Article, :count).by(1) 
    end 
    end 

    describe 'POST/create not' do 
    it 'did not create a new user' do 
    # expect(art_params).to receive(attributes_for :article).with(content:) 
     art_params = { article: attributes_for(:article, content: nil) } 
     post :create, art_params 
     expect(response).to render_template(:new) 
    end 
    end 

    describe 'GET/edit' do 
    it 'displays the edit template' do 
     get :edit, id: article.id 
     expect(response).to render_template(:edit) 
    end 
    end 

    describe 'POST/update' do 
    it 'displays the update template' do 
     post :update, id: article.id, article: attributes_for(:article) 
     expect(response).to redirect_to(article_path(article.id)) 
    end 
    end 

    describe 'POST/DELETE' do 
    it 'destroys the article template' do 
     dbl = double() 
     article = create :article 
     expect { delete :destroy, id: article.id }.to change(Article, :count).by(-1) 

    end 
    end 
en 

d

+1

Mocks und Stubs sollten meiner Meinung nach nicht so viel im Controller-Code verwendet werden. Denn Controller-Aktionen sollen klein, kompakt und einfach zu bedienen sein. Stubs werden mehr in Komponententests verwendet, um zum Beispiel Callbacks in Tests loszuwerden oder eine lange Methode oder eine Anfrage eines Dritten zu stubben. – Kkulikovskis

+0

Richtig, aber es könnte in einigen Fällen nützlich sein. Zum Beispiel könnten Sie sich über einen Aufruf von 'ActiveRecord # save' lustig machen, wenn Sie beispielsweise möchten, dass Ihre Tests schneller ablaufen und nicht jedes Mal die Datenbank treffen. – born4new

Antwort

1
# This is a stub 
    fake_article = allow(article).to receive(:compute_price).and_return(200) 

    # This too 
    another_fake_article = double(compute_price: 200) 

    # This is a mock 
    expect(article).to receive(:where).with(status: :closed) 

Der letzte wird fehlschlagen, wenn Ihr Artikel nicht den Hash where Methode mit dem { status: :closed } Parameter nicht nennen. Ich hoffe, das hilft.

2

Mocking und Stubbing ist ziemlich fortgeschritten Test-Konzept, um es richtig zu machen. Ohne echtes Verständnis ist es leicht, fragile Tests zu erstellen, die jedes Mal brechen, wenn der getestete Code geändert wird. Oder Tests, die immer bestehen werden.

Zum Beispiel kann der folgende Code niemals fehlschlagen. Sie erstellen einen Testdoppelwert (dbl). Dann stubben Sie eine Methode (#articles) für diesen Doppeleintrag und geben an, dass dieser Methodenaufruf die Instanz article zurückgibt. In der Erwartung rufen Sie die #articles Methode auf dem Testdoppel auf, die passieren muss, da Sie gerade dieses Verhalten auf dem Testdoppel definiert haben.

let(:article) { create :article } 
let(:dbl) { double(:articles) } # the test double 

it 'assigns @articles' do 
    get :index 
    allow(dbl).to receive(:articles).and_return article # stubbing 
    expect(dbl.articles).to eql(article) # invoking the stubbed method 
end 

Sie können versuchen, get :index Linie aus diesem Beispiel zu entfernen, und Sie werden sehen, dass der Code noch passiert.

Sie könnten das Beispiel schreiben, ohne genausogut zu Anstoßen:

let(:article) { create :article } 

it 'assigns @articles' do 
    get :index 
    expect(assigns(:articles)).to contain_exactly(article) 
end 

Wenn Sie die Programmierung mit Rails und RSpec gestartet werden, würde ich mit realen Objekten empfehlen, wann immer Sie können. Die Dokumentation für rspec-rails hat viele gute Beispiele: http://www.relishapp.com/rspec/rspec-rails/v/3-4/docs Wenn Sie mehr über Mocking und Stubbing erfahren möchten, ist die RSpec-Dokumentation auch ein guter Platz dafür.

+0

@ Laura: Vielen Dank! –