yre*_*uta 1 rspec ruby-on-rails ruby-on-rails-4
所以我有这个型号代码:
def self.cleanup
Transaction.where("created_at < ?", 30.days.ago).destroy_all
end
Run Code Online (Sandbox Code Playgroud)
而这个rspec单元测试:
describe 'self.cleanup' do
before(:each) do
@transaction = Transaction.create(seller:item.user, buyer:user, item:item, created_at:6.weeks.ago)
end
it 'destroys all transactions more than 30 days' do
Transaction.cleanup
expect(@transaction).not_to exist_in_database
end
end
Run Code Online (Sandbox Code Playgroud)
与这些工厂:
FactoryGirl.define do
factory :transaction do
association :seller, factory: :user, username: 'IAMSeller'
association :buyer, factory: :user, username: 'IAmBuyer'
association :item
end
factory :old_transaction, parent: :transaction do
created_at 6.weeks.ago
end
end
Run Code Online (Sandbox Code Playgroud)
使用此rspec自定义匹配器:
RSpec::Matchers.define :exist_in_database do
match do |actual|
actual.class.exists?(actual.id)
end
end
Run Code Online (Sandbox Code Playgroud)
当我将规格更改为:
describe 'self.cleanup' do
let(:old_transaction){FactoryGirl.create(:old_transaction)}
it 'destroys all transactions more than 30 days' do
Transaction.cleanup
expect(old_transaction).not_to exist_in_database
end
end
Run Code Online (Sandbox Code Playgroud)
测试失败了.我还尝试手动创建一个事务并将其分配给:old_transaction with let()但这也使测试失败.
为什么它只在我在before(:each)块中使用实例变量时才通过?
提前致谢!
编辑:失败的输出
1) Transaction self.cleanup destroys all transactions more than 30 days
Failure/Error: expect(old_transaction).not_to exist_in_database
expected #<Transaction id: 2, seller_id: 3, buyer_id: 4, item_id: 2, transaction_date: nil, created_at: "2014-02-26 10:06:30", updated_at: "2014-04-09 10:06:32", buyer_confirmed: false, seller_confirmed: false, cancelled: false> not to exist in database
# ./spec/models/transaction_spec.rb:40:in `block (3 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)
let很懒.所以在你失败的规范中,这是事件的顺序:
Transaction.cleanupold_transaction = FactoryGirl.create(:old_transaction)expect(old_transaction).not_to exist_in_database因此,在您尝试清理之后创建事务.
有多种选择:
let用于此除非你有其他规格想要告诉其他开发者:
我完全打算让所有这些规范引用完全相同的对象
我个人觉得,你最好在内联交易.
it do
transaction = FactoryGirl.create(:old_transaction)
Transaction.cleanup
expect(transaction).not_to exist_in_database
end
Run Code Online (Sandbox Code Playgroud)
change匹配器这是我个人的选择,因为它清楚地表明了预期的行为:
it do
expect{
Transaction.cleanup
}.to change{ Transaction.exists?(old_transaction.id) }.to false
end
Run Code Online (Sandbox Code Playgroud)
这适用let于change块在块之前和之后运行expect.所以在第一次传递时,old_transaction实例化它id可以被检查.
before或参考old_transactionIMO这看起来很奇怪:
before do
old_transaction
end
it do
old_transaction # if you don't use the before
Transaction.clean
# ...
end
Run Code Online (Sandbox Code Playgroud)
let!这let!不是懒惰的.从本质上讲,它是做正常的别名let,然后在a中调用它before.我不是这种方法的粉丝(请参阅The bang是为了解释细节的原因).
| 归档时间: |
|
| 查看次数: |
648 次 |
| 最近记录: |