rails将类常量重构到数据库对应的表中之二

    在博文之一中我们将Order中的常量重构到了数据库的表中,也做了一些测试,貌似一切都很完美.可是...梦魔还未开始啊!我们少做了一步测试,就是rake test!

    结果惨不忍睹,所有测试都是E,全部出错!提示payment_types表中找不到字段type!这个很好解决,检查test/fixtures/payment_types.yml文件,发现其中字段名称还是type,将其改为pay_type,则所有E都消失鸟.

    可是噩梦还未结束!仍然有2个F!检查发现无论是在Order中还是Order控制器中动态赋予的:PaymentType.all.map {|type|type.pay_type}在rake test中统统都为nil值,而且在测试开头的setup中设置也不行!如果还原Order中的:

  PAYMENT_TYPES = ["Check","Credit card","Purchase order"]

则没有问题.不太了解test背后的机制,为毛不能应用动态的值呢?还是百思不得其"姐"中...

    思来想去,想要放弃又不太甘心啊!静下心来重新理一下思绪吧:

首先test测试用的是test数据库中的内容,如果正常流程执行没有问题而测试过不去的话,是不是test数据库里面有问题呢?抱着试一试的心态,用sqlite3 test.sqlite3打开test数据库,检查里面的payment_types表内容,果真没有东东啊!难怪出现上面字段都为nil的情况啊!下面的就是如何在test的数据库中添加pay_type的问题了.

    首先第一次尝试:在seeds.rb中增加如下代码:

PaymentType.delete_all
PaymentType.create(pay_type:'Check')
PaymentType.create(pay_type:'Credit card')
PaymentType.create(pay_type:'Purchase order')

运行rake db:seed,检查test数据库还是没有记录.思考发现以上代码貌似是在development上下文中执行的,也就是说它把记录添加到development.sqlite3数据库中去了啊!我们可以让其在test上下文中执行:

RAILS_ENV=test rake db:seed

再次检查test数据库,终于有内容了!但是别急着高兴哦!再次rake test还是出错,错误相同!再次查看test数据库中的内容:又被清空了.遂猜测到test的运行机制:首先清空test数据库,然后再做测试!那么解决起来就简单鸟:

首先在test/test_helper.rb中添加一个新的方法init_payment_types:

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  def init_payment_types
    PaymentType.delete_all
    PaymentType.create(pay_type:'Check')
    PaymentType.create(pay_type:'Credit card')
    PaymentType.create(pay_type:'Purchase order')
  end
  # Add more helper methods to be used by all tests here...
end

然后修改test出错的控制器test类OrderControllerTest中的setup方法的block:

class OrdersControllerTest < ActionController::TestCase
  setup do
    #Order::PAYMENT_TYPES = PaymentType.all.map {|type|type.pay_type}
    init_payment_types
    @order = orders(:one)
  end
end

再测试一下,咦怎么还是不行啊,错误依旧!?进一步检查发现:虽然setup中手动预先插入了支付方式记录,但是貌似model Order工作方式如下:在test中Order Class会首先初始化,注意这早于setup的执行;意味着这时test数据库中还是没有内容;执行到validates :pay_type,inclusion:PaymentType.types一句时会生成类似代码:

validates :pay_type,inclusion:[#空的数组]

等到以后在Order控制器测试时虽然执行了setup,但是以后的create和update测试方法的model检查用的还是一开始生成的[#空的数组],所以还是执行不通过!一种办法是在rake test之前调用RAILS_ENV=test rake db:seed;或者只有早于第一次Order Class初始化在test数据库中插入payment_types,在一番搜索后,发现可以在config/initizlizers下加入初始化ruby脚本来实现该功能:

首先在上述目录下建立新文件:make_payment_types.rb,加入以下代码:

if Rails.env == "test"
  PaymentType.delete_all
  PaymentType.create(pay_type:'Check')
  PaymentType.create(pay_type:'Credit card')
  PaymentType.create(pay_type:'Purchase order')
end

我们只需要在测试试才用执行该脚本哦;或者为了不违背DRY原则,我们可以在make_payment_types.rb中这样写:

if Rails.env == "test"
  load 'db/seeds.rb'
end

    经过一番折腾,终于全部测试通过啦!但是还别急啊,这样重构总觉得哪里有问题,感觉很别扭,本猫觉(Jiao三声)着还是要重构哦!要知最后大结局请看博文之三吧! :)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值