rspec测试协会 [英] rspec testing association

查看:46
本文介绍了rspec测试协会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的 rspec 控制器测试中测试员工是否与公司相关联.

I want to test that a staff member is associated with a company in my rspec controller tests.

我想在人员控制器的 create 操作中结束:

I would like to end up with this in my create action of the staff controller:

staff.companies << current_company

其中 current_company 是从会话变量中收集的.

Where current_company is collected from a session variable.

我该如何为此编写测试?

How do I write a test for this?

我有这些模型

class Company < ActiveRecord::Base
  has_many :employees
  has_many :staff, :through => :employees
end

class Employee < ActiveRecord::Base
  belongs_to :company
  belongs_to :staff
end

class Staff < ActiveRecord::Base
  has_many :employees
  has_many :companies, :through => :employees
end

以下测试是我尝试规范关联,但在我输入关联代码时失败:

The following test is my attempt to spec the assocation and it fails when I enter in the association code:

    it "should belong to the current_company" do
      staff.should_receive(:companies)
      post :create
    end

如果我输入'staff.companies <<current_company' 代码在我的控制器中运行该测试时出现此错误:

If I enter the 'staff.companies << current_company' code in my controller I get this error when running that test:

 Failure/Error: post :create
 NoMethodError:
   You have a nil object when you didn't expect it!
   You might have expected an instance of Array.
   The error occurred while evaluating nil.<<

员工控制器创建方法:

  def create
    @staff = Staff.new(params[:staff])

    if @staff.save
      @staff.companies << current_company
      redirect_to staff_index_path, :notice => "Staff created successfully!"
    else
      @company = @staff.firm || current_company
      flash[:alert] = "Staff failed to create"
      render "new"
    end
  end

推荐答案

我会使用不同的方法,因为测试模型应该接收特定消息会使您的测试与实现过于紧密地结合在一起.您真的关心公司是否收到 #<< 或其他方法?

I would use a different approach, since testing that the model should receive a certain message couples your tests too tightly to the implementation. Do you really care whether companies receives #<< or some other method?

实际上,您要测试的是用户的公司在发布到页面时是否被记录.如何记录它并不重要.所以我会做这样的事情:

Really, what you want to test is whether the user's company is recorded when they post to the page. It doesn't matter how it was recorded. So I'd do something like this:

it "should add the company to the user's list of companies" do
  lambda do 
    post :create
  end.should change(staff.companies, :count).from(0).to(1)
  staff.companies.map(&:name).should include("Acme, Inc.")
end

这是测试行为而不是实现.优点是当有人将 << 更改为等效的 push 时,您的测试不会失败.它还具有更清晰的意图,从而更好地记录代码的优点.

This is testing behavior instead of implementation. The advantage is that your test wont fail when someone changes that << to the equivalent push. It also has the advantage of being clearer about your intention and therefore better documenting the code.

这篇关于rspec测试协会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆