Rails测试涉及需要api更新的对象

时间:2011-08-03 11:03:04

标签: ruby-on-rails unit-testing testing mocking

我正在尝试使用Bill对象来执行测试。这是一个美国国会议案,我在xml中通过rsync在数据目录中。我的代码采用账单名称,比如“h1.xml”,解析xml,然后从www.govtrack.us获取账单的全文。所以,在我的主应用程序中,创建一个账单

  • 获取帐单名称(例如h1)(通过def self.update_from_directory方法中的globbing)
  def self.update_from_directory
    Dir.glob("#{Rails.root}/data/bills/small_set/*.xml").each do |bill_path|
      bill_name = bill_path.match(/.*\/(.*).xml$/)[1]
      b = Bill.find_or_create_by(:govtrack_name => bill_name)
      b.update_bill
      b.save!
    end
  end
  • 更新帐单
def update_bill
    file_data = File.new("#{Rails.root}/data/bills/#{self.govtrack_name}.xml", 'r')
    bill = Feedzirra::Parser::GovTrackBill.parse(file_data)
    if bill && (self.introduced_date.nil? || (bill.introduced_date.to_date > self.introduced_date))

      self.congress = bill.congress
      self.bill_type = bill.bill_type
      self.bill_number = bill.bill_number
      ... and so on . . . until:
      get_bill_text 
  • 使用帐单文本
  • 更新帐单记录
  def get_bill_text
      bill_object = HTTParty.get("#{GOVTRACK_URL}data/us/bills.text/#{self.congress.to_s}/#{self.bill_type}/#{self.bill_type + self.bill_number.to_s}.html")
      self.bill_html = bill_object.response.body
      self.text_updated_on = Date.today
      Rails.logger.info "Updated Bill Text for #{self.ident}"
  end

我的目标非常简单,我想模拟整个账单进行测试:

    def setup
       @my_test_bill = Bill.new(:govtrack_id => "h1")
       @my_test_bill.update_bill
    end

我正在努力让webmock和vcr工作,但我能找到的所有示例都提供了一种模拟特定调用的方法,我不想重新键入一个全新的update_bill方法。

任何想法都非常感激。

1 个答案:

答案 0 :(得分:1)

考虑将update_bill方法更改为:

def update_bill
  file_data = File.new("#{Rails.root}/data/bills/#{self.govtrack_name}.xml", 'r')
  bill = Feedzirra::Parser::GovTrackBill.parse(file_data)
  if bill && (self.introduced_date.nil? || (bill.introduced_date.to_date > self.introduced_date))

  self.congress = bill.congress
  self.bill_type = bill.bill_type
  self.bill_number = bill.bill_number

  # Yield to a block that can perform arbitrary calls on this bill
  if block_given?
    yield(self)
  end

  # Fill bill text if empty
  if bill_html.blank? && text_updated_on.blank?
    get_bill_text
  end
end

然后将您的设置方法更改为:

def setup
   @my_test_bill = Bill.new(:govtrack_id => "h1")
   @my_test_bill.update_bill do |bill|
     bill.text_updated_on = Date.today
     bill.bill_html = "The mock bill contents"
   end
end

这可能不完全是解决方案,但是这种方法 - 将接收器传递回给定方法的块,允许您在运行时修改给定方法的确切行为。