【发布时间】:2017-04-09 15:13:18
【问题描述】:
当我运行整个测试套件时,MyClass.inspect 返回不正确的类。
问题:
我在项目中有 User::CreditCard 和 ActiveMerchant::Billing::CreditCard 课程。最后来自 activemerchant 宝石。
当我运行单一规格(rspec spec/models/user/credit_card_spec.rb)时,它可以正常工作。
当我运行整个套件(rspec spec)时,规范失败并显示undefined method...,没关系。 问题是,在这种情况下,我的CreditCard 课程不是我的!!!
当我运行单一规范并执行puts User::CreditCard.inpsect(或只是p User::CreditCard,或者只是User::CreditCard)时,它会按预期返回User::CreditCard。
当我运行整个套件并在规范中执行 p User::CreditCard 时,它会返回 ActiveMerchant::Billing::CreditCard。
背景:
如果您不想阅读“背景”,请确保最后有 NOTE
我正在使用遗留代码。所以我并不完全了解图像的所有部分。
我想在我的用户中为信用卡创建Value Object。所以我创建了新的无表模型(注意路径和类名):
#app/models/user/credit_card.rb
class User::CreditCard
include ActiveModel::Model
delegate :card_number, :card_expiration, :card_type, to: :subscription
def initialize(subscription)
@subscription = subscription || Subscription.new
end
private
attr_reader :subscription
end
当然我有用户模型:
#app/models/user.rb
class User
...
has_one :subscription
...
def credit_card
@credit_card ||= User::CreditCard.new(subscription)
end
end
我的用户/信用卡规格:
#spec/models/user/credit_card_spec.rb
require 'spec_helper'
# require 'user/credit_card' # if I include this then it works correct
RSpec.describe User::CreditCard, type: :model do
let(:subscription) { build :subscription }
let(:credit_card) do
p User::CreditCard # this result depends on whole/not whole suite run...
# rspec spec => ActiveMerchant::Billing::CreditCard
# rspec spec/models/user => User::CreditCard
User::CreditCard.new(subscription)
end
it 'should delegate alowed messages to user subscription' do
%w[card_number card_expiration card_type].each do |attr|
expect(credit_card.public_send(attr)).to eql subscription.public_send(attr)
end
end
it 'disallow another methods' do
expect { credit_card.unexisted_method }.to raise_error(NoMethodError)
end
end
注意:
在规范中,我可以要求 'user/credit_card' 然后它会起作用。但是为什么没有它就不行呢? 会不会是其他地方的问题?例如在控制器或其他地方?
【问题讨论】:
-
@mudasobwa 我不确定这是否易于复制...
-
无论如何,我猜问题根源在
class User::CreditCard。 Rails 确实是巫毒自动加载,因为你有class User,所以User是一个类或模块之间存在冲突。尝试将User::CreditCard重命名为module UserDetails; class CredirCard。听起来很奇怪,但没有逻辑,也没有预测如何处理自动加载。 -
@mudasobwa
…Minimal – Use as little code as possible that still produces the same problem- 我不确定它是否可以通过一小段代码来复制。…Complete – Provide all parts needed to reproduce the problem- 我不确定我应该在complete我的问题中添加什么... -
忘掉 MCVE,听起来就在这里。 Rails 的经验法则是:避免命名空间冲突,尤其是类和模块之间。
-
太棒了!它有效:) 但对我来说很奇怪 %)
标签: ruby-on-rails ruby rspec activemerchant value-objects