Rspec Rails:使用多模型表单测试控制器方法'create'

时间:2012-06-25 23:19:12

标签: ruby-on-rails rspec controller update-attributes

我正在使用通常的各种模型,视图和控制器构建Ruby on Rails应用程序。

我的一个控制器中的'create'动作应该创建两个不同模型的实例。这是我的代码:

 def create
  @league = League.new(params[:league])
  @user = @league.users.build(params[:user])
  ... .save conditions appended ...
 end

因此,当您通过对联盟的POST请求通过LeaguesController调用'create'时,您将获得一个新的League实例和一个新的User实例。我还希望新的User实例继承新的League实例的ID,因此它可以用作将实例链接在一起的外键。这是通过以下方式完成的:

 def create
  @league = League.new(params[:league])
  @user = @league.users.build(params[:user])
  @league_id = @league.id
  @user.update_attribute('league_id', @league_id)
  ... .save conditions appended ...
 end

用户模型已经belongs_to联盟模型,has_many个用户。

以上代码工作正常,花花公子,通过手动测试验证。但是,我不能为我的生活弄清楚如何使用Rspec自动化这些测试。我想成为一个好孩子,并使用测试驱动的设计,但这让我很难过。

问题是我无法弄清楚如何在我的测试中访问新创建的League和User实例的属性。我试图使用以下代码执行此操作:

describe LeaguesController do
  describe 'new league and user' do
    it 'should create a new user with a league_id equal to the new leagues id'
      @league_attr = { :name => "myleague", :confirmation_code => "mycode", :id => 5}
      @user_attr = { :username => "myname", :password => "mypass"}
      post :create, :user => @user_attr, :league => @league_attr
      assigns(:league_id).should eql(5)
    end
  end
end

但是测试会返回nil以获取:league_id

的值

我对一般编程和特别是Rspec都很陌生,所以我非常感谢有人提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

您无法将:idnew分配。试试这个:

 def create
   @league = League.new(params[:league])
   @league.id = params[:league][:id] if params[:league][:id]
   @user = @league.users.build(params[:user])
   @league_id = @league.id
   @user.update_attribute('league_id', @league_id)
   ... .save conditions appended ...
 end

那就是说,我想知道它是如何在浏览器中运行的。

此外,最好在测试时使用FactoryGirl或Fixtures为模型分配数据。

答案 1 :(得分:0)

您是否尝试过pry

每当我发现这样的东西时,我发现能够通过Pry(或Ruby-Debug)插入制动点非常方便,所以我可以检查变量及其行为。

我怀疑在binding.pry@league_id = @league.id之间放置@user.update_attribute('league_id', @league_id)可能会很好地阐明这个问题。

另请注意,当您通过@league.save调用将其保留时,用户将自动继承@league_id。 (这是@league.users.build(..)背后的想法 - 它将在持久性时正确设置所需的关系。