测试模型的Rails说“预期错误是真的”。

时间:2018-04-16 16:51:54

标签: ruby-on-rails ruby testing

我有一个网站,用户可以在注册时创建产品,产品可以有清单。

我有一个包含以下列的清单表: -

id  |  product_id  | content  |  archived 

我是铁轨测试的新手。我在下面写了测试

  test 'should have content' do
    checklist = Checklist.new
    assert checklist.save
  end

并使用以下命令运行测试

ruby -I test test/models/checklist_test.rb

并且测试失败,预期错误为真正错误。

是否因为问题可以使用user.product.checklists访问清单我必须首先填充灯具中的数据并调用那些进行测试?

编辑1

我没有在清单模型中进行任何验证。

class Checklist < ApplicationRecord belongs_to :product end

我在测试保存中添加,如下所示

  test 'should have content' do
    checklist = Checklist.new
    assert checklist.save!
  end

并收到此错误

  

ActiveRecord :: RecordInvalid:验证失败:产品必须存在

因为表中有product_id。我不知道如何向rails测试提供数据。有什么帮助吗?

编辑2

如下编辑后,错误消除。

class Checklist < ApplicationRecord belongs_to :product, optional: true end

但是我想用product来测试模型。我不知道如何使用灯具为测试提供数据,就好像没有外键我可以在测试中使用Checklist.new

由于它有外键,我如何向Checklist提供数据,因为它属于Product本身属于User

2 个答案:

答案 0 :(得分:5)

如果checklist.save由于某种原因未能保存,

false将返回checklist;可能是因为验证失败

例如,您的app/models/checklists.rb可能包含以下内容:

validates :product_id, presence: true

或者:

validates :content, length: { minimum: 10 }

等。在这个简单的场景中,您可以通过查看模型定义轻松确定错误;但是对于更复杂的应用程序,您可以查看:checklist.errors.messages以查看记录无法保存的原因列表。

根据测试名称判断(“应该有内容”),我的猜测是失败,因为content不能为空!

例如,要使此测试通过,您可能需要编写:

test 'should have content' do
  checklist = Checklist.new(content: 'hello world')
  assert checklist.save
end

人们在测试此类事物时使用的一种常见方法是在factories中定义“有效记录”;这使您可以显式测试无效记录,而不必在许多地方显式重新定义有效记录。例如,您可以这样做:

# test/factories/checklists.rb
FactoryBot.define do
  factory :checklist do
    content 'test content'
  end
end

# test/models/checklist_test.rb
test 'should have content' do
  checklist = build(:checklist, content: nil)
  refute checklist.save # Expecting this to FAIL!
  assert_includes "Content cannot be nil", checklist.errors
end

(代码可能不是100%完整/准确;但你明白了)

答案 1 :(得分:0)

我已经学会了Fixtures来解决这个问题。

灯具的设计方式甚至可以完成相关数据(模型中的关联)。例如,在我的测试中,我写了

checklist = checklists(:one)

获取清单的测试数据。在清单夹具(checklists.yml)

  one:
    product: one
    content: Entry
    hashtag: '#markets'
    archived: false
    done: false

,其中

product: one

products.yml 中的:一个数据

  one:
   user: one
   name: Test
   role: Will decide

因此完成了固定装置的关联。