2012-06-25 50 views
2

我正在构建一个Ruby on Rails应用程序,其中包含常见的模型,视图和控制器。Rspec Rails:使用多模型表单测试控制器方法'创建'

在我的控制器之一中的“创建”操作应该创建两个不同模型的实例。这里是我的代码:

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

所以,当你通过POST请求/联赛,你会得到联盟的新实例和用户的新实例调用“创造”通过LeaguesController。我还希望新的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自动化这些测试。我试图成为一个好孩子,并使用测试驱动设计,但这让我很难过。

问题是我不知道如何在我的测试中访问新创建的联盟和用户实例的属性。我试图这样做,用下面的代码:

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 

但对于:league_id

我是新来的,一般和RSpec特别是两个编程值测试返回nil,所以我真的很感激任何人可能提供的帮助!

回答

0

你试过pry

每当我发现这样的事情我觉得很方便,以便能够通过撬(或Ruby-调试)插入brakepoint这样我就可以检查变量和他们的行为。

我怀疑在@league_id = @league.id@user.update_attribute('league_id', @league_id)之间插入binding.pry可能很好地说明了这个问题。

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

+0

感谢Tigraine,我会检查出撬,我觉得在这样信心的方法是窝国王(它的行为如预期),但我想使用自动化Rspec的,这样我可以确保我的应用程序变得更加复杂,我不打破这个功能测试。 –

1

你不能用new分配:id试试这个:

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或者灯具测试时分配的数据模型。

+0

谢谢你的回应,Wawa Loo。我认为它的工作原理是因为我实际上不需要分配':id'。每次创建新模型实例时都会自动分配它。我只是读取已存在的值,并将其值分配给不同模型实例中的不同属性。 –

+0

其实,一个新的不会分配'id'。它必须先保存。我认为没有用,因为你在做'@user = @ league.users.build(params [:user])','@league_id = @ league.id'这行没有任何帮助。 (请考虑接受答案,如果它是你所期望的) –

+0

那么,你的测试正在完成他们的工作。他们告诉你,你的控制器动作create有一个问题:它不适合提供':id'作为参数,并且当保存2个关联模型时,你应该使用另一个方法(一个事务 - 肯定 - 创建用户,联盟并通过直到他们正确关联)。 –