ruby-on-rails - 使用 RSpec 和 FactoryGirl 测试模型中的 Rails 类方法的正确方法是什么?

标签 ruby-on-rails ruby unit-testing rspec tdd

我必须测试类别 Rails 模型,与 rspec 和 Factory Girl 隔离。我开始使用 FactoryGirl 定义一个类别(记录),如下所示:

#spec/factories/category.rb
FactoryGirl.define do
  factory :category do |f|
    f.name "A/B Testing"
    f.tags_array %w(test a/b)
  end
end

和类别模型规范如下:

# spec/models/category_spec.rb
require 'spec_helper'

  describe "Category" do
    before(:each) do
      @category = FactoryGirl.create(:category)
    end
    it "has a valid factory" do
      @category.should be_valid
    end
    it "is invalid without a name" do
      @category.name = nil
      @category.should_not be_valid
    end
    it "is invalid without at last one tag" do
      @category.tags_array = nil
      @category.should_not be_valid
    end
  end

现在我应该定义并测试一个 Category 类方法,它返回一个 competitors 数组,其中 Competitor 是一个 Struct 对象,就像以下:

  Object.const_set :Competitor, Struct.new(:html_url, :description, :watchers, :forks)

那么这个类方法seff.find_competitors_by_tags应该返回一个结构数组(:Competitor Struct对象数组):

  def self.find_competitors_by_tags(tags_array)
    competitors = []
    Extractor.each do |wl|
      competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
    end
    return competitors
  end

使用 RSpec 和 FactoryGirl 单独测试此功能的最佳方法是什么?我的想法如下,但我不能说清楚:

spec/factories/competitor.rb
FactoryGirl.define do
  factory :competitor do |f|
    f.html_url "https://github.com/assaf/vanity"
    f.description "Experiment Driven Development for Ruby"
    f.watchers "844"
    f.forks "146"
  end
end

# spec/models/category_spec.rb
require 'spec_helper'

  describe "Category" do
    ...
    ...

    it "returns a list of all competitors for each category" do
      competitors << FactoryGirl.create(:competitor) 
      competitors << Factory.build(:competitor, html_url: "https://github.com/andrew/split",
                                   description: "Rack Based AB testing framework",
                                   watchers: "357",
                                   forks: "42")
      @category.find_competitors_by_tags("A/B Testing").should == competitors
    end
  end

无论如何它都不起作用,我也不确定它是否有意义:

Failures:

      1) Category returns a list of all competitors for each category
         Failure/Error: @competitors << FactoryGirl.create(:competitor)
         NameError:
           uninitialized constant Competitor
         # ./spec/models/category_spec.rb:22:in `block (2 levels) in <top (required)>'

测试这样的方法的正确方法是什么?

最佳答案

您询问如何单独测试它:

 def self.find_competitors_by_tags(tags_array)
    competitors = []
    Extractor.each do |wl|
      competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
    end
    return competitors
  end

主要问题是对 Extractor.each 的调用...您应该将数组发送到此方法并反转此依赖关系。任何时候你的方法要自己获取信息,这都会导致测试变得困难。所以像这样:

def self.find_competitors_by_tags(extractions, tags_array)
  extractions.map do |wl|
    Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
  end
end

然后您可以轻松发送并测试它:

let(:extractions) {[ stub(:competitor), {html_url: "url", description: "description", watchers: "watchers", forks: "forks"] }

it "should map the extractions" do
  competitors = Class.find_competitors_by_tags(extractions, nil)
  competitors.first.html_url.should eq("url")
  #continue
end

最后一点:tags_array 似乎未使用。

关于ruby-on-rails - 使用 RSpec 和 FactoryGirl 测试模型中的 Rails 类方法的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11065519/

相关文章:

javascript - 如何从 JavaScript 上的 Rails 访问环境变量?

mysql - OSX 10.11 El Capitan 上的 Rails : Library not loaded: libmysqlclient. 18.dylib

ruby-on-rails - 寻找有关如何匹配模式的想法,可能与否?

ruby-on-rails - 将 header 添加到 rspec get

unit-testing - 如何使用 Jasmine 和/或 Sinon 正确地对 jQuery 的 .ajax() promise 进行单元测试?

java - PowerMock 模拟具有有限数据访问的私有(private)方法

python - 在 django 中对抽象 View 进行单元测试

ruby-on-rails - ActiveRecord 如何忽略挂起的迁移

ruby-on-rails - 如何在 Rails 应用程序中测试简单的 Ruby 类?

ruby-on-rails - Rails 公共(public)目录的绝对 URL