如何使用步骤测试控制器以使用某些操作

时间:2013-04-29 17:18:25

标签: ruby-on-rails rspec devise controller

在我的系统中,我有一个用户,其中一个公司有多个帐户 用户使用Devise登录系统,并在CompaniesController中设置名为selected_company的虚拟属性 我希望在这个场景中在AccountsController中进行多次测试 我有这个代码签署用户,这段代码效果很好:

before :each do
  @user = create(:user)
  @user.confirm!
  sign_in @user
end  

但我必须要有一个特定的上下文,我试图编码为:

context 'when user already selected a company' do
  before :each do
    @company = create(:company)
    @account = create(:account)
    @company.accounts << @account
    @user.selected_company = @company
  end

  it "GET #index must assings @accounts with selected_company.accounts" do
    get :index
    expect(assigns(accounts)).to match_array [@account]
  end
end

但是这段代码不起作用,当我运行它时出现了这个错误:

undefined method `accounts' for nil:NilClass

我的AccountsController #index只有以下代码:

def index
  @accounts = current_user.selected_company.accounts
end

我是rspec和TDD的新手,我有时间测试我想要的一切,我想测试一切来练习rspec。
我不知道这是否是测试这些东西的最佳方式,所以我愿意接受建议。

3 个答案:

答案 0 :(得分:0)

替换为:

expect(assigns(:accounts)).to match_array [@accounts]

注意,:accounts而非account 另外,正如我所看到的,您的规范中没有@accounts。请同样声明。 :)

答案 1 :(得分:0)

可能你没有保存selected_company,当你在你的控制器上调用它时,它返回nil。

设置selected_company后尝试保存@user.save

context 'when user already selected a company' do
  before :each do
    @company = create(:company)
    @account = create(:account)
    @company.accounts << @account
    @user.selected_company = @company
    @user.save
  end

  it "GET #index must assings @accounts with selected_company.accounts" do
    get :index
    expect(assigns(accounts)).to match_array [@account]
  end
end

希望能帮到你。

答案 2 :(得分:0)

最后,我发现了问题! 我将before语句更改为:

before :each do
  @company = create(:company)
  @account = create(:account)
  @company.accounts << @account
  controller.current_user.selected_company = @company
end

并在expect方法中将assigns(accounts)更改为assings(:accounts)(带符号)。