英文:
How to stub parent and child class in rspec
问题
I apologize for any confusion, but it seems there are some HTML encoding issues in your code that make it difficult to understand. Additionally, the code you provided is not entirely clear, and it's not entirely clear what you want to translate. However, I'll try to provide some guidance based on the code you provided:
你的Rails(v7)应用中有一个类结构,类似于这样:
# app/services/email_notifier.rb
class EmailNotifier
def notify(template_data)
# 使用电子邮件客户端执行操作
end
end
# app/services/email_notifier/template_data.rb
class EmailNotifier
class TemplateData
def fill_in
# 使用模板和电子邮件客户端执行操作
end
end
end
# app/services/notification_service.rb
class NotificationService
def call
template_content = EmailNotifier::TemplateData.new(name: 'John Doe')
EmailNotifier.notify(template_content)
end
end
我理解你想要验证类方法是否被调用。你遇到的问题可能是:
- 当运行测试时,类加载器可能无法正确解释你的结构。
- "父"类被存根化,无法获取其"子"类。
鉴于我猜测问题可能出现在第2点,你可能可以尝试使用stub_const
。以下是你提供的RSpec测试的一些翻译:
# spec/services/notification_service.rb
require 'rails_helper'
RSpec.describe NotificationService do
subject(:service) { described_class.new }
let(:email_notifier) { class_double(EmailNotifier).as_stubbed_const }
let(:email_template_class) { class_double(EmailNotifier::TemplateData).as_stubbed_const }
let(:email_template) { instance_double(EmailNotifier::TemplateData) }
before do
allow(email_notifier).to receive(:notify)
allow(email_template_class).to receive(:new).and_return(email_template) # 修复此处
allow(email_template).to receive(:fill_in)
end
it 'fills the template in' do
service.call
expect(email_template).to have_received(:fill_in)
end
end
请确保你正确使用as_stubbed_const
来存根化类和模块。希望这有助于解决你的问题。如果你需要更多帮助,请提供更多细节或清晰的问题描述。
英文:
I have a class structure in a Rails (v7) app that looks like this:
# app/services/email_notifier.rb
class EmailNotifier
def notify(template_data)
# do things with email client
end
end
# app/services/email_notifier/template_data.rb
class EmailNotifier
class TemplateData
def fill_in
# do things with template and email client
end
end
end
# app/services/notification_service.rb
class NotificationService
def call
template_content = EmailNotifier::TemplateData.new(name: 'John Doe')
EmailNotifier.notify(template_content)
end
end
And what I'm trying to do is verify that the class methods are called:
# spec/services/notification_service.rb
require 'rails_helper'
RSpec.describe NotificationService do
subject(:service) { described_class.new }
let(:email_notifier) { class_double(EmailNotifier).as_stubbed_const }
let(:email_template_class) { class_double(EmailNotifier::TemplateData).as_stubbed_const }
let(:email_template) { instance_double(EmailNotifier::TemplateData) }
before do
allow(email_notifier).to receive(:notify)
allow(email_template_class).to receive(:new).and_return(:email_template)
allow(email_template).to receive(:fill_in)
end
it 'fills the template in' do
service.call
expect(email_template).to have_received(:fill_in)
end
end
When I run rspec, I get this error:
NameError:
uninitialized constant #<ClassDouble(EmailNotifier) (anonymous)>::TemplateData
template_content = EmailNotifier::TemplateData.new
Now, I understand that I could be facing a problem from different origins:
- the structure I use is not being correctly interpreted by class loader when running the spec
- the "parent" class is stubbed and it cannot get its "child" class
As I suspect that what is happening is 2., the question is how can I make this kind of stub happen? Is this possible? Am I facing it in a wrong way?
I'm not sure stub_const
works either as I expect in this spec.
答案1
得分: 0
为什么在存根方法时要模拟类?
英文:
Why mock the classes when you're stubbing the methods?
allow(EmailNotifier).to receive(:notify)
allow(EmailNotifier::TemplateData).to receive(:fill_in)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论