Question | Click to View Answer |
Create a new Rails application called controller_tdd. Add rspec_rails to the Gemfile. Install RSpec. |
$ rails new controller_tdd
Gemfile
group :development, :test do
gem "rspec-rails"
end
$ bundle exec rails generate rspec:install
|
Use the Rails resource generator to create files for an Article MVC with a title string attribute and a body text attribute. |
$ rails g resource Article title body:text
$ rake db:migrate
|
Write a controller test to make sure the ArticlesController#index action sets the @articles instance variable to be an array of all the articles in the database. |
spec/controllers/articles_controller_spec.rb
describe "GET index" do
it "assigns all articles as @articles" do
article = Article.create!(title: "valid title")
get :index
assigns(:articles).should eq([article])
end
end
|
Write code to make the test pass. |
# spec/controllers/articles_controller.rb
def index
@articles = Article.all
end
Make the following file: app/views/articles/index.html.erb |
Write a controller test to make sure the ArticlesController#show action sets the @article instance variable to the article that corresponds with the id in the parameters. |
describe "GET show" do
it "assigns the requested article as @article" do
article = Article.create!(title: "valid title")
get :show, {:id => article.to_param}
expect(assigns(:article)).to eq article
end
end
|
Write code to make the test pass. |
# spec/controllers/articles_controller.rb
def show
@article = Article.find(params[:id])
end
Make the following file: app/views/articles/show.html.erb |
Write a controller test to make sure the ArticlesController#edit action sets the @article instance variable to the article that corresponds with the id in the parameters. |
spec/controllers/articles_controller_spec.rb
describe "GET edit" do
it "assigns the requested article as @article" do
article = Article.create!(title: "valid title")
get :edit, {:id => article.to_param}
assigns(:article).should eq(article)
end
end
|
Write code to make the test pass. |
# app/controllers/articles_controller.rb
def edit
@article = Article.find(params[:id])
end
Make the file app/views/articles/edit.html.erb |
Write a controller tests to make sure the ArticlesController#create action creates a new article, thereby increasing the number of articles by one. |
spec/controllers/articles_controller_spec.rb
describe "POST create" do
it "creates a new article" do
parameters = {article: {title: 'valid title'}}
expect {post :create, parameters}.to change(Article, :count).by(1)
end
end
|
Write code to make the test pass. |
# app/controllers/articles_controller.rb
def create
@article = Article.create(article_params)
redirect_to @article
end
private
def article_params
params.require(:article).permit(:title, :body)
end
|
Write a controller test to make sure the ArticlesController#create action assigns the newly created article to @article. |
it "assigns a newly created article as @article" do
post :create, {:article => {title: 'valid title'}}
expect(assigns(:article)).to be_a(Article)
expect(assigns(:article)).to be_persisted
end
The tests should already be passing from the code we wrote for the previous example. |
Write a controller test to make sure the ArticlesController#create action redirects to the newly created article. |
it "redirects to the created article" do
post :create, {:article => {title: 'valid title'}}
expect(response).to redirect_to(Article.last)
end
This test should already be passing from code that’s already been written. |
Write a controller test to make sure the ArticlesController#create action assigns a newly created but unsaved article as @article when the parameters are invalid. |
spec/controllers/articles_controller_spec.rb
it "assigns a newly created but unsaved article as @article with invalid parameters" do
Article.any_instance.stub(:save).and_return(false)
post :create, {:article => { "title" => "invalid value" }}
expect(assigns(:article)).to be_a_new(Article)
end
|
Update the code to make the test pass. |
# app/controllers/articles_controller.rb
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :index
end
end
|
Write a controller test to make sure the ArticlesController#create action renders the new page when the parameters are invalid. |
# spec/controllers/articles_controller_spec.rb
it "re-renders the 'new' template with invalid parameters" do
Article.any_instance.stub(:save).and_return(false)
post :create, {article: {title: "invalid value" }}
expect(response).to render_template("new")
end
|
Write code to make the test pass. |
# app/controllers/articles_controller.rb
def new; end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new
end
end
Make the following file: app/views/articles/new.html.erb |
Write a controller test to make sure that the ArticlesController#update action updates an article. |
# spec/controllers/articles_controller_spec.rb
describe "PUT update" do
it "updates the requested article" do
article = Article.create!(title: "something")
Article.any_instance.should_receive(:update).with({ "title" => "new title" })
put :update, {:id => article.to_param, :article => { "title" => "new title" }}
end
end
|
Write code to make the test pass. |
# app/controllers/articles_controller.rb
def update
@article = Article.find(params[:id])
@article.update(article_params)
redirect_to articles_path
end
|
Add a test to make sure the ArticlesController#update action assigns the @article instance variable to the requested article. |
# spec/controllers/articles_controller_spec.rb
it "assigns the requested article as @article" do
article = Article.create!(title: 'something')
put :update, {:id => article.to_param, :article => {"title" => "new title"}}
assigns(:article).should eq(article)
end
This test should be passing from code that was already added. |
Add a test to make sure that the ArticlesController#update action redirects to the article show page after the article is updated. |
# spec/controllers/artices_controller_spec.rb
it "redirects to the article" do
article = Article.create!(title: 'something')
put :update, {:id => article.to_param, :article => {"title" => "new title"}}
expect(response).to redirect_to(article)
end
|
Update the code to make the test pass. |
# app/controllers/articles_controller.rb
def update
@article = Article.find(params[:id])
@article.update(article_params)
redirect_to @article
end
|
Write a test to make sure the ArticlesController#destroy action deletes an article. |
# spec/controllers/articles_controller_spec.rb
describe "DELETE destroy" do
it "destroys the requested article" do
article = Article.create!(title: 'something')
expect do
delete :destroy, {:id => article.to_param}
end.to change(Article, :count).by(-1)
end
end
|
Update the code to make the test pass. |
# app/controllers/articles_controller.rb
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
|
Write a test to make sure the ArticlesController#destroy action redirects to the index page. |
# spec/controllers/articles_controller_spec.rb
it "redirects to the posts list" do
article = Article.create!(title: "something")
delete :destroy, {:id => article.to_param}
expect(response).to redirect_to(articles_url)
end
|