【问题标题】:rspec test that uses dummy data from an entire table in rails app database使用 rails app 数据库中整个表中的虚拟数据的 rspec 测试
【发布时间】:2019-02-02 08:53:47
【问题描述】:

我想编写一个使用MyModel.all(即模型的所有记录)并用它做一些事情并返回结果的 rspec 测试

是否可以从 rspec 中生成新的数据库表(即模型)?然后在测试结束时销毁它?这是否被认为是好的做法(理论上,如果从事该项目的开发人员巧合地制作了一个同名的表,并且它可能会被测试丢弃)。或者这是否被认为不太可能在测试中生成一个随机命名的表?

注意:测试必须提取模型中的所有记录,因此为什么最好在测试中简单地生成一个(非常小的),而不是使用实际的表,这可能会很大并且不必要地减慢测试

我尝试测试的方法是

def my_method(model_name)
  the_table = eval(model_name).all

  # does some things

end

该方法的关键特性是它接受模型名称(并检索模型方法中的所有记录)

测试是这样的

it "ensures something" do

  # tests

  expect(result).to eq(true)

end

【问题讨论】:

  • 测试通常是隔离的,因此您可以使用受控夹具为测试数据库播种。使用动态/实时数据通常是不好的做法。此外,它对测试实际应用程序中不存在的模型没有用处,你为什么要测试它呢?你检查过FactoryBot gem吗?它很容易用于为测试播种数据,
  • @bo-oz 我会看看 FactoryBot。基本上我有一个将整个表作为输入的方法。所以测试它的唯一方法(我认为)是给它它需要的东西(整张桌子)。该表绝对不必是应用程序中使用的确切表 - 它可以是一个只有几条记录的小表,可能有 5 列
  • 阅读有关模拟和存根的 RSpec 文档。如果没有看到您正在尝试测试的代码,很难说出您需要做什么,但我们通常可以使用替代对象来表示将在执行期间调用的代码部分,但我们对在给定的测试中不感兴趣的功能测试。例如,我们不想测试 MyModel.all,因为它是一个库方法,我们假设它像宣传的那样工作。
  • @PaulByrne 这听起来是个好方法,除了该方法实际上接受模型的名称(例如"Mymodel")并且在方法内部调用eval(model).all 来检索表
  • 没关系。模拟对象是关于以指定响应响应某些消息的替身。你为什么不发布你拥有的代码。

标签: ruby-on-rails ruby rspec ruby-on-rails-5 rspec-rails


【解决方案1】:

这是一个简单的解决方案

Rails 会自动创建一个与 dev/prod 具有相同架构的测试数据库。因此,您需要做的就是在运行测试之前添加一些数据

例如

# Add some records 
@model_name = Model_name.new(name: "John", email: "john@gmail.com")
@model_name.save

# run your test
it "ensures something" do

  # tests

  expect(result).to eq(true)

end

另请注意:

  • 您的 rspec 测试将使用 test 数据库,它与您的开发数据库的结构完全相同,只是它开始时为空(因此您必须向其中添加一些数据)
  • 您可以像使用开发(或生产)数据库一样轻松地将数据放入测试数据库中
  • 请注意,您对 spec.rb 文件中的测试数据库所做的任何操作都将在测试完成后回滚

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多