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三声)着还是要重构哦!要知最后大结局请看博文之三吧! :)

相关文章
|
Java 关系型数据库 MySQL
JDBC连接数据库工具类
JDBC连接数据库工具类
|
4月前
|
SQL NoSQL 关系型数据库
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
56 2
|
6月前
|
消息中间件 Java 数据库连接
【消息队列开发】 对核心类实现数据库管理
【消息队列开发】 对核心类实现数据库管理
|
2月前
|
运维 NoSQL BI
简道云搭载阿里云MongoDB数据库,帮助数以万计企业重构业务系统
通过与MongoDB和阿里云团队的合作,让简道云少走了弯路,保障了线上服务的长期稳定运行,提高了吞吐效率,并相应降低了线上运行成本
|
4月前
|
SQL Java 关系型数据库
应用DriverManager类创建sqlserver数据库连接实例 JSP中使用数据库
该博客文章介绍了在JSP中使用JDBC连接SQL Server数据库的方法,包括加载数据库驱动、建立数据库连接的过程,并提供了一个使用DriverManager类创建数据库连接的Java示例代码。
|
5月前
|
SQL 安全 数据库
Ruby on Rails 数据库迁移操作深度解析
【7月更文挑战第19天】Rails 的数据库迁移功能是一个强大的工具,它帮助开发者以版本控制的方式管理数据库结构的变更。通过遵循最佳实践,并合理利用 Rails 提供的迁移命令和方法,我们可以更加高效、安全地管理数据库结构,确保应用的稳定性和可扩展性。
|
6月前
|
关系型数据库 Java MySQL
Java关于Mysql数据库的事物处理类
Java关于Mysql数据库的事物处理类
22 0
|
7月前
|
SQL Java 数据库连接
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
53 0
|
7月前
|
数据库
将连接数据库封装成类
在idea里将连接数据库封装成类
|
7月前
|
JavaScript Java 关系型数据库
基于vue的MOBA类游戏攻略分享平台23(程序+数据库+论文)可帮忙远程调试
基于vue的MOBA类游戏攻略分享平台23(程序+数据库+论文)可帮忙远程调试