此测试通过:
it 'test' do
old = parenthood.student.balance
Payment.money_transfer_to_child current_user: parenthood.user,
student_id: parenthood.student.id,
amount: '1',
comment: 'some comment'
expect(parenthood.student.reload.balance).to eq(old+1)
end
将其更改为以下形式会使其无法通过("已被0更改"):
subject { Payment.money_transfer_to_child current_user: parenthood.user,
student_id: parenthood.student.id,
amount: '1',
comment: 'some comment' }
it { expect{ subject }.to change(parenthood.student.reload, :balance).by(1) }
我做错了什么?
我知道你找到了一种让它发挥作用的方法,但也许我们在这里有一个合适的答案。那么首先为什么它不起作用。
it { expect{ subject }.to change(parenthood.student.reload, :balance).by(1) }
当这一行被执行时,所做的是(不完全但大致):
- 首先计算了变化方法的参数。这意味着
parenthood.student.reload
在该点被评估 - 对已评估的对象调用平衡方法,并记住该值
- 执行预期中的块(在本例中仅为主题)
- 再次对对象调用平衡方法
这里的问题是在执行subject
之前对parenthood.student.reload
进行了评估。在执行subject
之后,它再也没有被计算过,因为它已经被传递给了change方法。这就是为什么你在那里有旧的价值观。
你可以做的是要么有你的解决方案(但这不是很优雅,因为重新加载父母身份不是你测试的一部分)。或者你可以在changematcher中使用这个块,然后做一些类似的事情:
it { expect{ subject }.to change { parenthood.student.reload.balance }.by(1) }
该语法使具有parenthood.student.reload.balance
的块在运行subject
之前和之后都进行了评估,并且应该修复您的测试。
在主题中添加一行解决了我的问题:
subject { Payment.money_transfer_to_child current_user: parenthood.user,
student_id: parenthood.student.id,
amount: '1',
comment: 'some comment'
parenthood.student.reload }