如何在控制器中指定范围内的新对象

时间:2010-09-06 16:50:41

标签: ruby-on-rails rspec

我应该如何规范这个嵌套版本:

#projects_controller.rb
def new
  @account.projects.build
end

到目前为止,我有这样的事情:

#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_return(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

不确定我应该怎么说这个...

2 个答案:

答案 0 :(得分:0)

一般来说,我建议尽可能少地进行抄写和嘲弄。我建议使用像Factory Girl这样的东西来创建真正的数据库对象,以便与测试进行交互。这意味着AccountProject将成为真正的ActiveRecord类,然后@account将是一个真正的AR对象,其projects关联就像在生产中一样。这很重要,因为否则你只是测试你编写的实现,并且在实际使用ActiveRecord时实际上没有测试过代码的功能。

一旦你能做到这一点,我建议你只需检查你关心项目模型的事情,例如:

assigns[:project].should be_instance_of(Project)
assigns[:project].should be_new_record
assigns[:project].account.should == logged_in_user

希望这有帮助!

答案 1 :(得分:0)

ProjectsController #new中缺少赋值。应该是:

def new
  # ...
  @project = @account.projects.build
  # ...
end

然后你可以按预期存根返回一个双击:

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