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

rails将类常量重构到数据库对应的表中之二的更多相关文章

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

    问题是这样:原来代码.html.erb页面中有一个select元素,其每个item对应的是model中的类常量: <%= f.select :pay_type,Order::PAYMENT_TY ...

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

    经过博文之一和之二的重构,貌似代码表现的还不错,正常运行和test都通过鸟,但是,感觉告诉我们还是有什么地方不对劲啊!究竟是哪里不对劲呢?我们再来好好看一下. 我们把数据库表中的支付方式集合直接放在实 ...

  3. rails将类常量重构到数据库对应的表之后记

    怎么还有啊!别急,有强迫症的人伤不起!有点小事没说完感觉痒痒的:就是如果表payment_types经常变动该怎么办?每次都要关闭rails网页服务器,然后重启吗?那也太麻烦鸟,最终的解决方案是,在O ...

  4. 【Java/JDBC】利用ResultSetMetaData从数据库的某表中获取字段信息并存到csv文件

    代码下载:https://files.cnblogs.com/files/xiandedanteng/FindNotnullColumns20191102-2.rar 这篇还不够完善,请看更完善的续篇 ...

  5. iOS-查询数据库-->指定数据表中的当前数据行的总数量

    很多时候,我们在查询一个表的时候,不想得到里面的记录内容,只是想简单的得到符合查询条件的记录条数. FMDB中有一个很简单的方法就可以实现,见下面的代码实例: #import "FMdata ...

  6. 转数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  7. Mysql 导出数据库和指定表中的数据

    参考地址:http://jingyan.baidu.com/article/b7001fe14240ab0e7282dde9.html [root@youo zw]# mysqldump -u roo ...

  8. 数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  9. 4.mysql数据库创建,表中创建模具模板脚本,mysql_SQL99标准连接查询(恩,外部连接,全外连接,交叉连接)

     mysql数据库创建,表创建模等模板脚本 -- 用root用户登录系统,运行脚本 -- 创建数据库 create database mydb61 character set utf8 ; -- ...

随机推荐

  1. 1.Android中解析json程序代码

    Android程序解析json数据可以通过gson的方式,这种情况需要导入相应的jar包.测试代码如下: @Override protected void onCreate(Bundle savedI ...

  2. android RecycleView Adapter简单封装

    早些时候我们使用系统提供个的BaseAdapter的时候为了满足大家的需要,我们总会对BaseAdapter做一层上层的封装,然后对于实际业务我们只需要关心getView里面的View即可,是代码可读 ...

  3. Android开发学习之路--UI之ListView

    这里再学习写android的ListView,其实我们都使用过ListView,就像手机的联系人,就是用的ListView了.下面就实现下简单的ListView吧,首先是xml文件中添加相关的代码: ...

  4. 【一天一道LeetCode】#260. Single Number III

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  5. python访问redis

    python访问redis 1 Linux上安装redis a) 下载 $ wget http://download.redis.io/releases/redis-3.0.5.tar.gz b) 编 ...

  6. J2EE学习从菜鸟变大鸟之七 Servlet

    Servlet现在自己的理解是一个控制器,简单的可以理解为不同的JSP页面由用户发送过来的请求可以由Servlet控制器来控制其向下调用的方向(结合三层好理解),但它比较特殊,因为它通常会从外界接收数 ...

  7. Android初级教程三个Dialog对话框小案例

    这里把三个对话框形式写在一个项目程序里面,用三个按钮控制显示什么样式的对话框. 先看布局文件代码: <LinearLayout xmlns:android="http://schema ...

  8. Docker教程:docker的概念及安装

    http://blog.csdn.net/pipisorry/article/details/50754385 Why docker 对于运维来说,Docker提供了一种可移植的标准化部署过程,使得规 ...

  9. LocalBroadcastManager—创建更高效、更安全的广播

    前言 在写Android应用时候,有时候或多或少的需要运用广播来解决某些需求,我们知道广播有一个特性,就是使用sendBroadcast(intent);发送广播时,手机内所有注册了Broadcast ...

  10. Java线程的状态

    Java线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在于Thread中的State枚举中,如下所示: public enum State { /** * 至今尚未启动的线程处于这种状 ...