试图围绕rspec和正确的测试,并且有一些困难时间正确地执行以下操作
假设我们有三个类,如
Class User
belongs_to :company
has_and_belongs_to_many :roles
end
Class Company
has_many :users
end
Class Role
has_and_belongs_to_many :users
end
在User类中,我有before_create回调,指定用户默认的'company_admin'角色,如果用户是第一个与公司关联的用户
def check_for_initial_company_admin_role
if self.company.users.count == 0
self.roles << Role.find_by_name("company_admin")
end
end
如何在我的模型规范中正确测试用户是否被分配了'company_admin'角色,以防他是与公司关联的第一个用户?
更新 工作解决方案
describe "#check_for_initial_company_admin_role" do
it "sets the first user created to be the administrator" do
Factory(:role)
user = Factory(:user)
user.roles.count.should be > 0
user.roles.should include Role.find_by_name("company_admin")
end
end
Factory.define :user do |f|
f.email { Factory.next(:email) }
f.password "secret"
f.password_confirmation "secret"
f.association :company
end
Factory.define :role do |f|
f.name "company_admin"
end
Factory.define :company do |f|
f.name "foobar"
f.vat_id "1234"
end
答案 0 :(得分:1)
我会这样做:
describe "#check_for_initial_company_admin_role" do
it "sets the first user created to be the administrator" do
company = Factory(:company)
user = Factory(:user)
company.users << user
user.roles.count.should > 0
user.roles.should include Role.find_by_name("company_admin")
end
end
这里可能不正确的假设是您在测试框架中使用Factory Girl。如果没有,这并没有真正改变这个测试的“肉”......只是你创建公司和用户的第一行。
您也可以选择从公司方面检查用户,但老实说,这完全是一个不同的测试 - 一个测试这些模型之间的关联。
我将采用的方法是,由于这实际上是一个模型测试,您需要创建和更改真实的模型对象,而不是模拟这些对象。如果这是一个控制器测试,我会嘲笑模型并积极地对模型进行存根。
我希望这有助于解决您的问题。如果没有,让我知道我不在哪里,我会再次通过它:)我只有一年的时间进入rspec但我发现一旦我绕过如何测试模型与控制器我已经爱上了它。
答案 1 :(得分:0)
在不改变现有逻辑的情况下,我会在user_spec中测试这个逻辑,如下所示:
describe User do
let!(:admin_role) { Role.create!(name: 'company_admin') }
let!(:company) { Company.create! }
it 'should be added to the default role when created' do
user = company.users.create!(name: 'Joe', email: 'joe@email.com')
user.should have(1).roles
user.roles.first.should == admin_role
end
end
注意:我会使用像FactoryGirl这样的东西来管理角色和公司对象,以使它们可以重复使用。
您使用角色名称来表示行为并不理想。它可能会导致整个应用程序中出现大量分散的逻辑,您可以通过其名称查找角色并使用if / else或case语句检查名称。我建议使用Rail的单表继承并将所有管理角色逻辑移动到单独的类。它将使模型的逻辑更清晰,并使测试更容易。