如何使用 shoulda-matchers gem 测试 rspec 中的关联?
How to test associations in rspec using shoulda-matchers gem?
您好,我正在学习使用 rspec 测试 rails 应用程序。我正在测试交易属于帐户的银行应用程序。我正在测试事务模型。它的代码如下:
Transaction.rb:
class Transaction < ApplicationRecord
validates :amount, presence: true, numericality: { only_integer: true,
greater_than: 0 }
after_create :update_balance
belongs_to :account
def update_balance
if transaction_type == 'debit'
account.current_balance -= amount
else
account.current_balance += amount
end
end
end
规格如下:
require 'rails_helper'
RSpec.describe Transaction, type: :model do
it { should belong_to(:account)}
subject {
described_class.new(amount: 60, transaction_type: 'credit',
id: 1,
created_at: DateTime.now, updated_at: DateTime.now,
account_id: 1)
}
it 'is valid with valid attributes' do
expect(subject).to be_valid
end
it 'is not valid without amount' do
subject.amount = nil
expect(subject).to_not be_valid
end
it 'is not valid without transaction type' do
subject.transaction_type = nil
expect(subject).to_not be_valid
end
it 'is not valid without created_at date' do
subject.created_at = nil
expect(subject).to_not be_valid
end
it 'is not valid without updated_at date' do
subject.updated_at = nil
expect(subject).to_not be_valid
end
it 'is not valid without transaction id' do
subject.id = nil
expect(subject).to_not be_valid
end
it 'is not valid without account id' do
subject.id = nil
expect(subject).to_not be_valid
end
end
我使用 shoulda gem 进行关联。然而,当我 运行 这个测试时,它会抛出错误,因为“帐户必须存在”,即使我已经添加了关联。
错误:
.F......
Failures:
1) Transaction is valid with valid attributes
Failure/Error: expect(subject).to be_valid
expected #<Transaction id: 1, transaction_type: "credit", amount: 0.6e2, created_at: "2018-11-13 10:33:13", updated_at: "2018-11-13 10:33:13", account_id: 1> to be valid, but got errors: Account must exist
# ./spec/models/transaction_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 0.02937 seconds (files took 0.77127 seconds to load)
8 examples, 1 failure
任何人都可以帮助理解我做错了什么吗?
P.S:事务 table 具有关联的 account_id 列。
提前致谢。
在Rails5中,默认需要定义为belongs_to
的关联。因此,当您检查 expect(subject).to be_valid
时,valid?
调用返回 false,因为您没有设置帐户。
让测试工作的方法将取决于您希望应用程序的对象模型看起来像什么。
如果交易可以在没有帐户的情况下存在,则以这种方式设置您的关联:
class Transaction < ApplicationRecord
belongs_to :account, optional: true
end
不过,我认为没有账户的交易更有可能是没有意义的。因此,您当前的测试实际上是正确的——当您测试无账户交易时,它无效。
在这种情况下,您可以相应地设置您的测试对象:
RSpec.describe Transaction, type: :model do
let(:account) { Account.new }
subject {
described_class.new( ..., account: account)
}
...
end
您好,我正在学习使用 rspec 测试 rails 应用程序。我正在测试交易属于帐户的银行应用程序。我正在测试事务模型。它的代码如下: Transaction.rb:
class Transaction < ApplicationRecord
validates :amount, presence: true, numericality: { only_integer: true,
greater_than: 0 }
after_create :update_balance
belongs_to :account
def update_balance
if transaction_type == 'debit'
account.current_balance -= amount
else
account.current_balance += amount
end
end
end
规格如下:
require 'rails_helper'
RSpec.describe Transaction, type: :model do
it { should belong_to(:account)}
subject {
described_class.new(amount: 60, transaction_type: 'credit',
id: 1,
created_at: DateTime.now, updated_at: DateTime.now,
account_id: 1)
}
it 'is valid with valid attributes' do
expect(subject).to be_valid
end
it 'is not valid without amount' do
subject.amount = nil
expect(subject).to_not be_valid
end
it 'is not valid without transaction type' do
subject.transaction_type = nil
expect(subject).to_not be_valid
end
it 'is not valid without created_at date' do
subject.created_at = nil
expect(subject).to_not be_valid
end
it 'is not valid without updated_at date' do
subject.updated_at = nil
expect(subject).to_not be_valid
end
it 'is not valid without transaction id' do
subject.id = nil
expect(subject).to_not be_valid
end
it 'is not valid without account id' do
subject.id = nil
expect(subject).to_not be_valid
end
end
我使用 shoulda gem 进行关联。然而,当我 运行 这个测试时,它会抛出错误,因为“帐户必须存在”,即使我已经添加了关联。
错误:
.F......
Failures:
1) Transaction is valid with valid attributes
Failure/Error: expect(subject).to be_valid
expected #<Transaction id: 1, transaction_type: "credit", amount: 0.6e2, created_at: "2018-11-13 10:33:13", updated_at: "2018-11-13 10:33:13", account_id: 1> to be valid, but got errors: Account must exist
# ./spec/models/transaction_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 0.02937 seconds (files took 0.77127 seconds to load)
8 examples, 1 failure
任何人都可以帮助理解我做错了什么吗?
P.S:事务 table 具有关联的 account_id 列。
提前致谢。
在Rails5中,默认需要定义为belongs_to
的关联。因此,当您检查 expect(subject).to be_valid
时,valid?
调用返回 false,因为您没有设置帐户。
让测试工作的方法将取决于您希望应用程序的对象模型看起来像什么。
如果交易可以在没有帐户的情况下存在,则以这种方式设置您的关联:
class Transaction < ApplicationRecord
belongs_to :account, optional: true
end
不过,我认为没有账户的交易更有可能是没有意义的。因此,您当前的测试实际上是正确的——当您测试无账户交易时,它无效。
在这种情况下,您可以相应地设置您的测试对象:
RSpec.describe Transaction, type: :model do
let(:account) { Account.new }
subject {
described_class.new( ..., account: account)
}
...
end