我有一段我想测试的代码:
class User < ActiveRecord::Base
has_many :servers, :dependent=> :destroy
end
请举例说明测试关联代码的RSpec代码。
答案 0 :(得分:8)
对我来说,这种变体效果很好:
describe User do
it { should have_many(:servers).dependent(:destroy) }
end
答案 1 :(得分:4)
在回答您当前的问题时,您现在可能会对此有所帮助,您真正需要的是了解测试。
您想为已经存在的代码编写测试。使用TDD方法,您将做相反的事情:首先编写测试,然后编写使测试通过的代码。
我建议您通过实用程序员购买RSpec Book。它会非常清楚地向您解释您应该做什么以及如何做。非常好的书,值得每一分钱。
另一个答案说你应该使用Shoulda。虽然这是一个很好的做法,但请先尝试自己做。一旦你理解了你应该做什么,那么你可以使用像Shoulda这样的抽象。
另一个答案使用工厂。虽然这是一个很好的做法,但我建议您首先使用RSpec内置工具,如Mock对象和存根方法。一旦了解了这两者的运作方式,就可以使用像Factories这样的抽象。顺便说一句,制作更简单。
答案 2 :(得分:1)
我在这里使用工厂女孩:
it "should be destroyed when user is destroyed" do
@user.servers << @server
@user.destroy
Server.all.should_not include(@server)
end
但您也可以在测试中创建一个新用户:
it "should be destroyed when user is destroyed" do
user = User.create(:name => "Julia")
user.servers << Server.create(:server_name => "Julias server")
user.destroy
Server.all.should_not include("Julias server")
end
答案 3 :(得分:1)
我提出了两种方法:快速和肮脏,以及D.R.Y和清洁:)
快速而肮脏:
context "when testing dependent: destroy" do
before do
@user = User.create
@servers = [Server.create]
@user.servers = @servers
end
it "should destroy all of the associated servers" do
@servers.each{|s| Server.exists?(s.id).should be_false}
end
end
要以干燥且可重复使用的方式执行此操作,仅依赖于rspec本身,您需要为HasMany定制匹配器。高级规范将如下所示:
Subject { User.new }
it { should have_many :tasks, dependent: :destroy }
然后匹配器将如下所示:
RSpec::Matchers.define :have_many do |_association, opts|
if opts and opts[:dependent]
match do |model|
associations(model, :has_many, opts).any? { |a| a == _association }
end
failure_message_for_should do |model|
error(
:expected => [ "%s to have many %s and to have dependent => :destroy %s", model, _association, opts[:dependent] ],
:actual => [ "%s has many %s ", model, associations(model, :has_many) ]
)
end
else
match do |model|
associations(model, :has_many).any? { |a| a == _association }
end
failure_message_for_should do |model|
error(
:expected => [ "%s to have many %s", model, _association ],
:actual => [ "%s has many %s", model, associations(model, :has_many) ]
)
end
end
end
您将需要此rspec辅助模块:http://pastie.org/6356719
我喜欢第一种方法,即使它很脏,因为它进入数据库并使用完整的rails堆栈...但有人认为这太过耦合了。第二种方法更干燥,但需要一个帮助,只是反映在关联本身,可能不会涵盖可能搞砸删除相关对象的其他问题......
答案 4 :(得分:0)
在RSpec中测试关联的一种方法是使用shoulda。 Shoulda是一组帮助者,可以快速编写常见的重复测试,同时可以理解。要测试您的模型,请确保已安装并需要shoulda gem。然后,您可以使用以下内容测试您的关联:
describe User do
it {should have_many :servers, :dependent => :destroy}
end
答案 5 :(得分:0)
对于简单的规范示例/代,我建议使用gem regressor:
https://github.com/ndea/regressor
此gem将根据关系/验证/数据库/回调为您的模型生成一些简单的规范,您可以在其中定位未来的规范。