我正在尝试改进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调用的问题,但其中大多数都提出了像VCR或webmock这样的宝石,它们似乎对这个特定的用例没有用处,因为我'我没有尝试复制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
答案 0 :(得分:1)
在我看来,你正在使用存根 - 模型/单元测试“应该”测试消息传递(同时数据库交互有效地由集成/验收测试覆盖)。
但是我认为你的方法虽然不是太复杂,但却试图做得太多,这会影响你编写干净测试的能力。 (对我来说,代码是说“我在哪里粘这个存根?”,并且几乎在那里锤击它!)
一个简单的建议可能是提取一些方法甚至类,因为cassandra_file
(raw_file
?)似乎有多个输入/输出或副作用,并且变得有点纠结。< / p>
它让人想起来自SOLID成名的单一责任原则(虽然有人说这个can't会描述Ruby中的方法)。我正在看到条件查询生成,数据库(外部系统)调用和文件输出。虽然这是一个相对较短的方法,但仍然有很多事情发生!
目前的一种思想模式都没有处理过这种情况的模型 - 它是所有PORO,“外包”到/ lib或其他地方,同时让ActiveRecord模型成为模型。 (所以瘦的控制器/脂肪模型被认为是第一步,这可能是下一步。)
如果你有时间和倾向,我建议花更多的时间来研究这个话题,因为有很多文章以及Ruby会议讨论它的有趣演讲。 (目前我正在挖掘Sandi Metz中的任何东西。)
如果没有,我会说你很接近,也许只是按照建议提取一些方法,并稍微简化模型,让自己的测试更容易。