【问题标题】:How to test class methods that rely on associations with RSpec and Sinatra?如何测试依赖于 RSpec 和 Sinatra 关联的类方法?
【发布时间】:2017-01-17 00:22:07
【问题描述】:

我已经编写了一些 RSpec 测试,这些测试成功地使用 :let 语句创建了对象。但是,测试环境不维护在其他任何地方都能正常运行的关联。下面是一个会出现 NoMethodError 的类的示例(nil:NilClass 的未定义方法 `money')。钱是库存中的一列。有什么想法吗?

class Inventory < ActiveRecord::Base
  belongs_to :character

  def self.return_money(character)
    character.inventory.money
  end
end

以下是规范文档的相应示例:

require 'spec_helper'

describe 'Test methods' do
  let(:trader) {
    Character.create(
      name: "Trader",
      location_id: 1)
  }
  let(:trader_inventory) {
    Inventory.create(
       character_id: trader.id,
       storage_capacity: 50000,
       money: 20000,
       markup: 1.35)
  }

  it "test method" do
    expect(Inventory.return_money(trader)).to eq(100)
  end

end

【问题讨论】:

  • 这个方法的目的是什么?作为 Inventory 的类方法,它在做什么?放置这种方法是一个非常奇怪的地方,尤其是当它作用于完全不同类型模型的实例时。
  • 我是为了举例而编造的。真正的方法有点复杂,但它需要两个字符,检查它们的库存/物品并在它们之间执行交易(如果有效)
  • 你可能想要创建一个一流的“交易”对象来处理它,以及某种可以评估交易是否合法、是否应该进行并确保它是正确处理。
  • 这很公平。除了方案,RSpec 是否能够使用关联?
  • Rspec 能够运行代码。如果该代码行使关联,当然可以。

标签: ruby activerecord rspec associations sinatra


【解决方案1】:

没有理由这不应该工作。 RSpec 并不特别,它只是普通的 Ruby 代码。您可以通过将所有代码移动到一个文件中来确认这一点,例如:

ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

class Inventory < ActiveRecord::Base
end
class Character < ActiveRecord::Base
  has_one :inventory
end

describe 'test' do
  it 'works' do
    puts Character.first.inventory.money.inspect
  end
end

猜测什么可能被破坏:

  • money 是一个复合字段或类似的东西。您可以发布您的数据库架构吗?
  • 库文件未正确加载。使用puts $LOADED_FEATURES 来验证所有应该需要的文件是否已经存在。

【讨论】:

  • 嘿 Xavier,回到这个话题。模型/表格是否需要在 spec_helper 中明确要求?
  • 可能是模型文件,是的。 IIRC 我不认为 Sinatra 自动加载的方式与Rails 不同。 (在您的规范中删除$LOADED_FEATURES 会告诉您是否需要模型文件)
猜你喜欢
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2015-03-29
  • 2017-07-08
相关资源
最近更新 更多