如何在RSpec中存根父类和子类

huangapple go评论51阅读模式
英文:

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

我理解你想要验证类方法是否被调用。你遇到的问题可能是:

  1. 当运行测试时,类加载器可能无法正确解释你的结构。
  2. "父"类被存根化,无法获取其"子"类。

鉴于我猜测问题可能出现在第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:

  1. the structure I use is not being correctly interpreted by class loader when running the spec
  2. 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)

huangapple
  • 本文由 发表于 2023年6月15日 01:07:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76476001.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定