rspec模型试验

rspec模型试验,rspec,Rspec,我有一段代码要测试: class User < ActiveRecord::Base has_many :servers, :dependent=> :destroy end class用户:销毁 结束 请给出测试关联代码的RSpec代码示例。在RSpec中测试关联的一种方法是使用。Shoulda是一个助手的集合,可以让常见的重复测试快速编写,同时又易于理解。要测试您的模型,请确保已安装并需要shoulda gem。然后,您可以测试与以下内容的关联: describe Us

我有一段代码要测试:

class User < ActiveRecord::Base

 has_many :servers, :dependent=> :destroy

end
class用户:销毁
结束

请给出测试关联代码的RSpec代码示例。

在RSpec中测试关联的一种方法是使用。Shoulda是一个助手的集合,可以让常见的重复测试快速编写,同时又易于理解。要测试您的模型,请确保已安装并需要shoulda gem。然后,您可以测试与以下内容的关联:

describe User do
  it {should have_many :servers, :dependent => :destroy}
end

这里我使用工厂女孩:

it "should be destroyed when user is destroyed" do
  @user.servers << @server
  @user.destroy
  Server.all.should_not include(@server)
end
它“应该在用户被销毁时销毁”do
@user.servers“Julia”)
user.servers“Julias服务器”)
用户破坏
Server.all.不应包括(“Julias服务器”)
结束

虽然现在回答您当前的问题可能会对您有所帮助,但您真正需要的是理解测试

您希望为已经存在的代码编写测试。使用TDD方法,您将做相反的事情:首先编写测试,然后编写使测试通过的代码

我建议您购买实用程序员编写的RSpec书籍。它将非常清楚地解释你应该做什么以及如何做。真是一本好书,值得每一分钱

另一个答案是你应该使用Shoulda。虽然这是一个很好的做法,但试着先自己做。一旦理解了应该做什么,就可以使用像Shoulda这样的抽象


另一个答案是使用工厂。虽然这是一个很好的实践,但我建议您首先使用RSpec内置工具,如Mock对象和stub方法。一旦您了解了这两种方法是如何操作的,那么您就可以使用类似于工厂的抽象。顺便说一句,制作更简单。

对我来说,这种变体效果很好:

describe User do
  it { should have_many(:servers).dependent(:destroy) }
end

我提出了两种方法:快速和肮脏,以及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定制一个匹配器。高级规范如下所示:

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
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帮助器模块:


我喜欢第一种方法,尽管它很脏,因为它进入数据库并使用完整的rails堆栈……但有人认为这太耦合了。第二种方法比较枯燥,但需要一个只对关联本身进行内省的助手,可能不会涵盖可能会导致关联对象删除失败的其他问题…

对于简单的规范示例/代,我建议使用gem回归器:


这个gem将根据关系/验证/数据库/回调为您的模型生成一些简单的规范,您可以根据这些规范来确定未来的规范。

我也采用了这种方法。当我将它放入模型测试时,它失败了——我得到了失败/错误:它{应该有很多(:服务器)}#。依赖(:destroy)}预期#响应
有多少?
在最新的rails/rspec中可能无效?我使用的是rails 4