How to spec a scoped new object in the controller
How should I spec this nested build:
#projects_controller.rb
def new
@account.projects.build
end
So far I have something like this:
#projects_controller_spec.rb
describe ProectssController do
describe "GET new" do
let(:account) { mock_model(Account) }
let(:project) { mock_model(Project).as_null_object }
before do
Account.stub(:find_by_subdomain!).and_retur开发者_JAVA百科n(account)
#Project.should_receive(:build).with(:account_id => account.id).and_return(project)
end
it "assigns @project" do
get :new
assigns[:project].should eq(project)
end
end
end
Not sure how I should be specing this...
The assignment is missing in ProjectsController#new. Should be:
def new
# ...
@project = @account.projects.build
# ...
end
Then you can stub returning a double as you intended:
it "assigns @project" do
account = mock_model(Account)
Account.stub(:find_by_subdomain!).and_return(account)
project = account.stub_chain(:projects,:build) { mock_model(Project) }
get :new
assigns(:project).should == project
end
In general, I recommend stubbing and mocking as little as possible. I recommend using something like Factory Girl to create real database objects for the tests to interact with. That means that Account
and Project
would be real ActiveRecord classes, and then @account
would be a real AR object with a projects
association that works just like it does in production. This is important, since otherwise you're just testing to the implementation you've written, and haven't actually tested that your code functions when it's actually using ActiveRecord.
Once you can do that, I would recommend simply checking things you care about for the Project model, e.g.:
assigns[:project].should be_instance_of(Project)
assigns[:project].should be_new_record
assigns[:project].account.should == logged_in_user
Hope this helps!
精彩评论