map*_*ap7 8 rspec2 ruby-on-rails-3
我想在我的rspec控制器测试中测试一名工作人员是否与公司相关联.
我想create在员工控制员的行动中最终得到这个:
staff.companies << current_company
Run Code Online (Sandbox Code Playgroud)
当current_company从一个会话变量收集.
我该如何为此编写测试?
我有这些型号
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
Run Code Online (Sandbox Code Playgroud)
以下测试是我尝试指定关联,当我输入关联代码时它失败:
it "should belong to the current_company" do
staff.should_receive(:companies)
post :create
end
Run Code Online (Sandbox Code Playgroud)
如果我在控制器中输入'staff.companies << current_company'代码,运行该测试时会出现此错误:
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.<<
Run Code Online (Sandbox Code Playgroud)
员工控制器创建方法:
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
Run Code Online (Sandbox Code Playgroud)
Ian*_*Ian 14
我会使用不同的方法,因为测试模型应该收到某个消息会将测试与实现过于紧密地联系在一起.您真的关心公司是否收到#<<或其他方法?
实际上,您要测试的是用户的公司在发布到页面时是否被记录.如何录制并不重要.所以我会做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
这是测试行为而不是实现.优点是当有人将其更改<<为等效时,您的测试不会失败push.它还具有更清晰的意图,因此更好地记录代码的优点.
| 归档时间: |
|
| 查看次数: |
4832 次 |
| 最近记录: |