使用RSpec测试依赖于外部Cassandra调用的方法

时间:2014-12-06 00:36:35

标签: ruby-on-rails ruby rspec cassandra

我正在尝试改进ActiveRecord模型的测试覆盖率,该模型通过查询Cassandra数据库来创建CSV文件。我们使用RSpec。我很难弄清楚如何测试下面显示的cassandra_file方法,因为它调用了cdbh(也显示如下),它创建了与Cassandra数据库的实时连接。

我尝试过这样的事情:

it 'copys from cassandra' do
  cdbh = Cassandra.stub(:connect)
  date = '2013/12/27'

  expect(device).to receive(:save_csv).with(date, cdbh.execute(options))
  device.raw_file(Date.new(2013,12,27))
end

但是我收到了这个错误:

Failures:

  1) Device raw_file generic device copys from cassandra
     Failure/Error: Unable to find matching line from backtrace
     NoMethodError:
       undefined method `stub' for Cassandra:Module

我查看了其他一些处理存根API调用的问题,但其中大多数都提出了像VCRwebmock这样的宝石,它们似乎对这个特定的用例没有用处,因为我'我没有尝试复制HTTP请求。有没有更好的方法来测试这个?这个测试是合理的,还是比它的价值更麻烦?

提前感谢您的帮助!

模型方法:

def cassandra_file(date)
  if customer.name.downcase == 'customer name'
    q = 'SELECT * FROM readings WHERE device = ? and date in (?, ?, ?)'
    return save_csv(
             date,
             cdbh.execute(q, guid, (date.to_date - 1).iso8601, date.to_date.iso8601, (date.to_date + 1).iso8601))
  else
    q = 'SELECT * FROM readings WHERE device = ? and date = ?'
    return save_csv(
             date,
             cdbh.execute(q, guid, date.to_date.iso8601))
  end
end

...

def cdbh
  return unless ENV['CASSANDRA_HOSTS']
  @cdbh ||= Cassandra.connect(hosts: ENV['CASSANDRA_HOSTS'].split(/,/)).connect('hurricane')
end

1 个答案:

答案 0 :(得分:1)

在我看来,你正在使用存根 - 模型/单元测试“应该”测试消息传递(同时数据库交互有效地由集成/验收测试覆盖)。

但是我认为你的方法虽然不是太复杂,但却试图做得太多,这会影响你编写干净测试的能力。 (对我来说,代码是说“我在哪里粘这个存根?”,并且几乎在那里锤击它!)

一个简单的建议可能是提取一些方法甚至类,因为cassandra_fileraw_file?)似乎有多个输入/输出或副作用,并且变得有点纠结。< / p>

它让人想起来自SOLID成名的单一责任原则(虽然有人说这个can't会描述Ruby中的方法)。我正在看到条件查询生成,数据库(外部系统)调用和文件输出。虽然这是一个相对较短的方法,但仍然有很多事情发生!

目前的一种思想模式都没有处理过这种情况的模型 - 它是所有PORO,“外包”到/ lib或其他地方,同时让ActiveRecord模型成为模型。 (所以瘦的控制器/脂肪模型被认为是第一步,这可能是下一步。)

如果你有时间和倾向,我建议花更多的时间来研究这个话题,因为有很多文章以及Ruby会议讨论它的有趣演讲。 (目前我正在挖掘Sandi Metz中的任何东西。)

如果没有,我会说你很接近,也许只是按照建议提取一些方法,并稍微简化模型,让自己的测试更容易。