我是rails的新手,我现在正试图使用stubbs和mock来测试我的控制器代码。我尝试在代码上使用mock但我无法正确执行。请帮我解决重构的正确代码。请帮我解释你写的代码。
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
答案 0 :(得分:2)
模拟和存根是相当先进的测试概念,以使其真正正确。如果没有真正的理解,很容易创建脆弱的测试,每次测试代码更改时都会中断。或者总是会通过的测试。
例如,以下代码不会失败。您创建一个测试double(dbl
),然后在该double上存根方法(#articles
)并指定此方法调用将返回实例article
。期望你在test double上调用#articles
方法,因为你刚刚在test double上定义了这个行为。
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
您可以尝试从该示例中删除get :index
行,您将看到代码仍在传递。
您也可以在没有存根的情况下编写示例:
let(:article) { create :article }
it 'assigns @articles' do
get :index
expect(assigns(:articles)).to contain_exactly(article)
end
如果您开始使用Rails和RSpec进行编程,我建议您尽可能使用真实对象。 rspec-rails的文档有很多很好的例子:http://www.relishapp.com/rspec/rspec-rails/v/3-4/docs 如果你想了解更多关于模拟和存根的信息,那么RSpec文档也是一个非常好的地方。
答案 1 :(得分: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)
如果您的文章没有使用where
参数哈希调用{ status: :closed }
方法,则最后一个将失败。希望有所帮助。