【发布时间】:2015-04-04 17:46:48
【问题描述】:
我正在使用原始/裸机 sql 插入来提高我的服务的写入性能。我的模块中有这样的东西 -
insert = "('#{id}', '#{status}', '#{some_time_val}')"
sql_string = "INSERT INTO history ('device_id', 'status', 'time') VALUES #{insert}"
ActiveRecord::Base.connection.execute sql_string
当我编写如下所示的 rspec 时,它会测试所有内容,除了插入是否通过。因此,由于 rspec、database_cleaner 等执行回滚和事务的方式,我的期望永远不会奏效。 我尝试使用
self.use_transactional_fixtures = false
和
before(:all) do
DatabaseCleaner.strategy = nil
end
但是插入仍然没有进入我的测试数据库
describe Worker do
let (:device1) {FactoryGirl.create(:device)}
let (:device2) {FactoryGirl.create(:device)}
let (:device3) {FactoryGirl.create(:device)}
self.use_transactional_fixtures = false
before(:all) do
DatabaseCleaner.strategy = nil
end
it "does something" do
devices = [{"status" => "Offline", "time" => "2013-09-17 18:17:17", "id" => device1.id},
{"status" => "Online", "time" => "2013-09-17 18:18:18", "id" => device2.id}]
Worker.any_instance.stubs(:devices).returns(devices) ## Not important for this question
Worker.new.perform
device1.reload.status.should == "Offline" # FAILS
end
end
我将如何测试这个?像这样测试原始 sql 插入的好策略是什么?
【问题讨论】:
-
您绝对不希望没有数据库清理。至少你想要截断。不清洗意味着测试污染。另请注意,您的查询存在 SQL 注入漏洞。
-
我想不出你不能“正常”测试这个的原因(我认为数据库清理器是一个红鲱鱼)。如果您使用正常的活动记录而不是
execute,您的测试是否通过(我似乎很奇怪,您正在重新加载现有对象以测试其状态,而您发布的 sn-p 似乎将新行插入到不同的表中) -
在沙盒控制台上运行查询时的输出是什么?在我看来,您的查询缺少最后一个“;”。
-
一般来说,这个工作流程是可测试的。我建议直接在您的数据库中验证您的 SQL。也许您需要使用严重字符而不是撇号(`device_id` 而不是 'device_id')...这取决于您的 SQL 引擎。
标签: ruby-on-rails ruby activerecord rspec