2014-07-01 102 views
1

我在哪里出错?使用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 

的 '应该改名换姓' 的结果是

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的助手,我知道每次调用它所创建的变量时都会得到一个新结果,这可能会导致错觉名称在'do work gadnammit'规范中发生变化。然而,将其更改为一个硬编码字符串产生没有任何区别:

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匹配器提供的db-query-matchers gem

TL; DR为什么不能

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

能工作?

回答

2

参数parent.folder.renamechange被调用时进行评估。在被测块执行后,它不会(也不能)重新评估。这很可能解释了为什么name调用所产生的对象不会改变。

如果你想表达被前后块的测试执行后重新评估,你需要传递change块为:

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

change作品中的“参数”版本当第一个参数保持不变(例如一个常量)并且与第二个参数相关联的方法返回的值改变时。

+0

谢谢彼得!耻辱它读得差不多和'expect {request} .to改变...'为什么'expect {delete:destroy,id:child_folder.id} .to改变(Folder,:count).by (-1)'工作?当然,在执行请求之前和之后必须评估“Folder.count”,那么为什么在查询实际记录时不起作用呢? – Starkers

+0

对,我要说实话我有点困惑。 '期待{ employee.develop_great_new_social_networking_app }。要改变(雇员:标题)。。从( “邮件办事员”)至( “CEO”)' 从 http://rubydoc.info/github/rspec/rspec-expectations/RSpec/Matchers#change-instance_method 非常接近匹配我想要的,但这不起作用?请举例:) – Starkers

+0

我不得不第二次问这个问题。没有注意到大括号,不理我:P – Starkers