期望{ 主题 }.to change(...)。by(1) 不起作用



此测试通过:

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) }

当这一行被执行时,所做的是(不完全但大致):

  1. 首先计算了变化方法的参数。这意味着parenthood.student.reload在该点被评估
  2. 对已评估的对象调用平衡方法,并记住该值
  3. 执行预期中的块(在本例中仅为主题)
  4. 再次对对象调用平衡方法

这里的问题是在执行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 }

最新更新