我有一个很大的问题。我已经开始将测试集成到我的rails应用程序中。它是现有数据库的管理系统。该应用程序运行良好,一切都已到位,但由于我决定使用rspec
测试数据库搞砸了。
每当我运行:rake db:test:clone
(我想克隆当前数据库以保存数据等)我得到一个mysql错误:
Invalid default value for 'active'
架构中有哪些:
t.string "active", limit: 0, default: "Yes", null: false
问题是limit:0
。有大约50个字段对它们有limit:0
,我很确定它们都是枚举/集合。解决这个问题的方法是什么?
答案 0 :(得分:2)
为什么不能使用FactoryGirl?
即使对于遗留数据库,您也必须能够使用Factory对模型建模,序列应该为您提供足够的唯一性,以便在规范运行时创建多个记录。如果你做不到,那么你遇到的问题比每次运行时重新创建测试数据库都要大,应该先解决。
您很可能尝试使用实际数据,因为您认为它最能代表数据中的随机性和真实性。但我怀疑它是否足以对您的代码进行压力测试。例如。你可以利用FFaker gem创建一个段落
Faker::Lorem.paragraph(1000)
这将测试数据库的文本字段。
# contrived factory example spec/factories/contrived_example_factory.rb
FactoryGirl.define do
factory :contrived_example do
description Faker::Lorem.paragraph(1000)
end
end
现在您可以使用多个记录来锤击数据库,您可能会发现数据库无法处理它。最好在测试中找到这个而不是在生产中。
如果使用FactoryGirl的let语法,除非需要,否则不会创建。 (尽管请记住,使用let语法,let块中的东西在你实际调用它之前不存在。)一旦你设置了工厂,就可以使用#create_list
从工厂创建一个数据列表。# In ContrivedExample Spec
let(:one_hundred_things) {FactoryGirl.create_list :your_factory_name_here, 100}
# And then Sample 1 item to use in your unit tests or integration tests.
let(:one_thing) {one_hundred_things.sample)
# in unit test
it("saves") {expect(one_thing.save).to be_true}
# in integration test
it("#show") do
get :show, id: one_thing.id
expect(assigns(:contrived_example)).to eq one_thing
end
将此与Database Cleaner gem结合使用,您可以在每次测试后重新开始。将它与Spork结合使用,您将在测试中利用dRB,这样可以加快测试线程能力的附加好处。 :)
同样,@ xlembouras指出设置限制:0会将你的varchars设置为0.可能不是你想要实现的。
答案 1 :(得分:1)
我看待它的方式有两个问题需要解决。
首先,(恕我直言)最严重的是您需要一个完整的数据库来测试您的应用程序。这是以前错误的设计决策的严重迹象。
其次(在您的问题中更多)您的数据库中似乎存在不一致。
我可能会弄错,但我认为limit: 0
是一个无效的选项。 (我认为字符串上的limit
显示varchar
的长度,但我对此没有信心。)
作为一种解决方法,您可以尝试使用rake db:test:prepare
而不是克隆。