Ruby on rails 使用RSpec测试依赖外部Cassandra调用的方法
我正试图提高ActiveRecord模型的测试覆盖率,该模型通过查询Cassandra数据库来创建CSV文件。我们使用RSpec。我很难弄清楚如何测试下面显示的Ruby on rails 使用RSpec测试依赖外部Cassandra调用的方法,ruby-on-rails,ruby,rspec,cassandra,Ruby On Rails,Ruby,Rspec,Cassandra,我正试图提高ActiveRecord模型的测试覆盖率,该模型通过查询Cassandra数据库来创建CSV文件。我们使用RSpec。我很难弄清楚如何测试下面显示的cassandra_文件方法,因为它调用cdbh(如下所示),从而创建到cassandra数据库的实时连接 我试过这样做: it 'copys from cassandra' do cdbh = Cassandra.stub(:connect) date = '2013/12/27' expect(device).to re
cassandra_文件
方法,因为它调用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调用的问题,但大多数建议使用的gem,如或,似乎对这个特定用例没有用处,因为我不尝试复制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
在我看来,您使用stubing的方法是正确的——模型/单元测试“应该”测试消息传递(而集成/验收测试有效地覆盖了数据库交互) 然而,我认为您的方法虽然不太复杂,但尝试做的太多,这影响了您编写干净测试的能力。(对我来说,代码是“我应该把这个存根放在哪里?”并且几乎是在那里敲打它!) 一个简单的建议可能是提取一些方法甚至类,因为
cassandra_文件(raw_文件
?)似乎有多个输入/输出或副作用,并且有点纠结
它让人想起了SOLID fame的单一责任原则(尽管有人说这可以用Ruby描述)。我看到了条件查询生成、数据库(外部系统)调用和文件输出。虽然这是一个相对较短的方法,但仍然有很多事情要做
目前有一个学派的模型没有处理这些问题——它们都是poro,“外包”到/lib或其他地方,而让ActiveRecord模型成为模型。(因此瘦控制器/胖模型被认为是第一步,这可能是下一步。)
如果你有时间和兴趣,我建议你花更多的时间研究这个话题,因为有很多文章以及Ruby会议上讨论这个话题的有趣演示。(目前我真的在从中挖掘任何东西。)
如果不是的话,我想说你很接近了,也许只需要按照建议提取一些方法,并简化模型,使自己的测试更容易。感谢您的全面回复。我的目标是重构这段代码,并按照您所说的去做,并将所有的比特提取到单独的方法中。然而,我希望得到保证,我没有回归功能,因此我希望在尝试分解其他人的代码之前,用测试覆盖当前代码。有什么建议吗?一种想法是,如果在重构之前需要保证,可以编写一个“哑”测试,只验证函数的正常输出,而不引入存根查询的复杂性。(换句话说,如果它要改变,为什么还要花更多的时间在它上面呢?)如果只是暂时的,稍微放慢测试套件的速度就没那么重要了。只是一个想法。。。