How can I describe of finding an associated model in the RSpec-rails controller examples?
I try the following:
Article
class Article < ActiveRecord::Base
has_many :comments
end
Comment
class Comment < ActiveRecord::Base
end
CommentsControllerSpec
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
before { Article.stub(:find) { article } }
before { article.stub(:comments) { [comment] } }
it 'finds a comment' do
article.comments.should_receive(:find) { comment }
put :update, article_id: article.id, id: comment.id
end
end
end
CommentsController
class CommentsController < ApplicationController
def update
Article.find.comments.find
end
end
But unfortunatelly it doesn't work. Any ideas?
Thanks.
I tackled the problem by myself.
Here's the approximate list of actions to describe of finding an associated model in the Rails' controllers.
1.
describe CommentsController do
describe 'update' do
end
end
2.
describe CommentsController do
describe 'update' do
it 'finds an article' # <=
end
end
3.
describe CommentsController do
describe 'update' do
it 'finds an article' do
Article.should_receive(:find) # <=
put :update # <=
end
end
end
4.
No route matches {:controller=>"comments", :action=>"update"}
5.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article } # <=
it 'finds a article' do
Article.should_receive(:find)
put :update, article_id: article.id # <=
end
end
end
6.
No route matches \
{:article_id=>"1025", :controller=>"comments", :action=>"update"}
7.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment } # <=
it 'finds an article' do
Article.should_receive(:find)
put :update, article_id: article.id, id: comment.id # <=
end
end
end
8.
(<Article (class)>).find(any args)
expected: 1 time
received: 0 times
9.
class CommentsController < ApplicationController
def update
Article.find
end
end
10.
Success!
11.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) # <=
put :update, article_id: article.id, id: comment.id
end
end
end
12.
<Article (class)> received :find with unexpected arguments
expected: ("1025")
got: (no args)
13.
class CommentsController < ApplicationController
def update
Article.find(params[:article_id]) # <=
end
end
14.
Success!
15.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) { # <=
mock(ActiveRecord::Associations::HasManyAssociation) # <=
} # <=
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s)
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do # <=
article.stub(:comments) { association } # <=
association.should_receive(:find) # <=
put :update, article_id: article.id, id: comment.id # <=
end # <=
end
end
16.
Couldn't find Article with id=1027
17.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
mock(ActiveRecord::Associations::HasManyAssociation)
}
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s)
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article } # <=
article.stub(:comments) { association }
association.should_receive(:find)
put :update, article_id: article.id, id: comment.id
end
end
end
18.
(Mock ActiveRecord::Associations::HasManyAssociation).find(any args)
expected: 1 time
received: 0 times
19.
class CommentsController < ApplicationController
def update
Article.find(params[:article_id]).comments.find # <=
end
end
20.
update
finds an article (fail!)
finds a comment (success!)
undefined method `comments' for nil:NilClass
21.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
mock(ActiveRecord::Associations::HasManyAssociation)
}
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article } # <=
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
article.stub(:comments) { association }
association.should_receive(:find)
put :update, article_id: article.id, id: comment.id
end
end
end
22.
update
finds an article (fail!)
finds a comment (success!)
Couldn't find Comment without an ID
23.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
mock(ActiveRecord::Associations::HasManyAssociation)
}
before { article.stub(:comments) { association } } # <=
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article }
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
# -> article.stub(:comments) { association } <-
association.should_receive(:find)
put :update, article_id: article.id, id: comment.id
end
end
end
24.
update
finds an article (fail!)
finds a comment (success!)
Mock ActiveRecord::Associations::HasManyAssociation \
received unexpected message :find with (no args)
25.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
mock(ActiveRecord::Associations::HasManyAssociation).as_null_object # <=
}
before { article.stub(:comments) { association } }
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article }
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
association.should_receive(:find)
put :update, article_id: article.id, id: comment.id
end
end
end
26.
Success!
27.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
mock(ActiveRecord::Associations::HasManyAssociation).as_null_object
}
before { article.stub(:comments) { association } }
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article }
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
association.should_receive(:find).with(comment.id.to_s) # <=
put :update, article_id: article.id, id: comment.id
end
end
end
28.
Mock ActiveRecord::Associations::HasManyAssociation \
received :find with unexpected arguments
expected: ("1028")
got: (no args)
29.
class CommentsController < ApplicationController
def update
Article.find(params[:article_id]).comments.find(params[:id]) # <=
end
end
30.
Success!
31.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
double(ActiveRecord::Associations::HasManyAssociation).as_null_object # <=
}
before { article.stub(:comments) { association } }
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article }
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
association.should_receive(:find).with(comment.id.to_s)
put :update, article_id: article.id, id: comment.id
end
it 'assigns @comment' do # <=
Article.stub(:find) { article } # <=
association.stub(:find) { comment } # <=
put :update, article_id: article.id, id: comment.id # <=
assigns[:comment].should eq comment # <=
end # <=
end
end
32.
expected: #<Comment >
got: nil
33.
class CommentsController < ApplicationController
def update
@comment = Article.find(params[:article_id]).comments.find(params[:id]) # <=
end
end
34.
Success!
35.
describe CommentsController do
describe 'update' do
let(:article) { stub_model Article }
let(:comment) { stub_model Comment }
let(:association) {
double(ActiveRecord::Associations::HasManyAssociation).as_null_object
}
before { article.stub(:comments) { association } }
it 'finds an article' do
Article.should_receive(:find).with(article.id.to_s) { article }
put :update, article_id: article.id, id: comment.id
end
it 'finds a comment' do
Article.stub(:find) { article }
association.should_receive(:find).with(comment.id.to_s)
put :update, article_id: article.id, id: comment.id
end
it 'assigns @article' do # <=
Article.stub(:find) { article } # <=
put :update, article_id: article.id, id: comment.id # <=
assigns[:article].should eq article # <=
end # <=
it 'assigns @comment' do
Article.stub(:find) { article }
association.stub(:find) { comment }
put :update, article_id: article.id, id: comment.id
assigns[:comment].should eq comment
end
end
end
36.
expected: #<Article >
got: nil
37.
class CommentsController < ApplicationController
def update
@article = Article.find(params[:article_id]) # <=
@comment = @article.comments.find(params[:id]) # <=
end
end
38.
Success!
39.
class CommentsController < ApplicationController
before_filter :find_article, only: :update # <=
before_filter :find_comment, only: :update # <=
def update
# -> @article = Article.find(params[:article_id]) <-
# -> @comment = @article.comments.find(params[:id]) <-
end
private # <=
def find_article # <=
@article = Article.find(params[:article_id]) # <=
end # <=
def find_comment # <=
@comment = @article.comments.find(params[:id]) # <=
end # <=
end
40.
Success!