使用rspec测试数据库记录

时间:2014-07-01 02:38:28

标签: rspec

我哪里错了?

 describe '#update' do
    let(:new_name) { Faker::Lorem.word }
    let(:request) { patch :update, id: parent_folder.id, folder: { name: new_name, parent_id: nil, user_id: user.id } }

    it 'should change the name' do
      expect{ request }.to change(parent_folder.reload,:name).from(parent_folder.name).to(new_name)
    end

    it 'does work gadnammit' do
      ap parent_folder.reload.name #=> e.g. aqua
      request
      ap parent_folder.reload.name #=> e.g. hortis
    end
  end

&#39>的结果应该更改名称'是

Failure/Error: expect{ request }.to change(parent_folder.reload,:name).from(parent_folder.name).to(new_name)# @new_name
expected #name to have changed from "maxime" to "jimmies", but did not change

然而'确实工作了gadnammit'记录两个不同的名称:

All examples were filtered out; ignoring {:focus=>true}
F."omnis"
"jimmies"

Failures:

1) FoldersController#update should change the name
     Failure/Error: expect{ request }.to change(parent_folder.reload,:name).from(parent_folder.name).to(new_name)# @new_name
       expected #name to have changed from "maxime" to "jimmies", but did not change
     # ./spec/controllers/folders_controller_spec.rb:62:in `block (3 levels) in <top (required)>'

此外,当你在Faker中使用let helper时,我知道每次调用它创建的变量时你都会得到一个新的结果,这可能会让人产生一种错觉,即#39中的名称正在改变。 ;工作gadnammit&#39;规范。但是,将其更改为硬编码字符串不会产生任何差异:

let(:new_name) { "stagnant" }

另外,这个规范:

it 'should make database queries' do
  expect{ request }.to make_database_queries 
end

通过,所以我真的觉得它有效...

SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
SELECT  "folders".* FROM "folders"  WHERE "folders"."user_id" = ? AND "folders"."id" = ? LIMIT 1
SAVEPOINT active_record_1
UPDATE "folders" SET "name" = ?, "updated_at" = ? WHERE "folders"."id" = 1
RELEASE SAVEPOINT active_record_1

(make_database_queries matcher由db-query-matchers gem提供)

TL; DR 为什么不

expect{ request }.to change(parent_folder.reload,:name).from(parent_folder.name).to(new_name)

工作?

1 个答案:

答案 0 :(得分:2)

在调用parent.folder.rename时评估参数change。在执行测试块之后,它不会(也不能)重新评估。这很可能解释了为什么调用结果对象的name不会改变。

如果要在执行测试块之前和之后重新评估表达式,则需要将change块传递给:

change { parent.folder.reload }.from(...).to(...)

change的“参数”版本在第一个参数保持不变(例如常量)时起作用,并且与第二个参数关联的方法返回的值发生变化。