铁轨+ RSPEC:测试该服务称为

发布于 2025-01-19 11:09:57 字数 2091 浏览 1 评论 0原文

我正在尝试编写一个测试,以确保我的服务 WeeklyReportCardService 已实例化,并且调用它的方法 :send_weekly_report_card_for_repositioning

这是控制器:

def update
    Audited.audit_class.as_user($user) do
        if @check_in.update(check_in_params)
            client = Client.find_by(id: check_in_params[:client_id])

            if @check_in.repositioning.present? && @check_in.weigh_in.present? && @check_in.client&.location&.name == "World Wide"

                # I see this in the console so the if statement returns true
                p "hitting send!!"

                WeeklyReportCardService.new.send_weekly_report_card_for_repositioning(@check_in.repositioning)
            end

            render json: @check_in, status: :ok, serializer: API::CheckInsIndexSerializer
        else
            render json: @check_in.errors.full_messages, sattus: :unprocessable_entity
        end
    end
end

这是我的测试:

RSpec.describe API::CheckInsController, type: :request do
    fit "should send if the client's location is World Wide" do
        program = create(:program, :with_client)
        worldwide = create(:location, name: "World Wide")
        program.client.update(location_id: worldwide.id)
        check_in = create(:check_in, client_id: program.client.id, program_id: program.id)
        create(:repositioning, check_in_id: check_in.id)
        create(:weigh_in, check_in_id: check_in.id)
        
        url = root_url[0..-2] + api_check_in_path(check_in.id) + "?sendReportCardEmail=true"

        put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }
        expect_any_instance_of(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
    end
end

我看到的错误是:

 Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }
   Exactly one instance should have received the following message(s) but didn't: send_weekly_report_card_for_repositioning

我还需要做什么来确保调用该函数?

I am trying to write a test to ensure that my service, WeeklyReportCardService, is instantiated and that it's method :send_weekly_report_card_for_repositioning is called.

Here's the controller:

def update
    Audited.audit_class.as_user($user) do
        if @check_in.update(check_in_params)
            client = Client.find_by(id: check_in_params[:client_id])

            if @check_in.repositioning.present? && @check_in.weigh_in.present? && @check_in.client&.location&.name == "World Wide"

                # I see this in the console so the if statement returns true
                p "hitting send!!"

                WeeklyReportCardService.new.send_weekly_report_card_for_repositioning(@check_in.repositioning)
            end

            render json: @check_in, status: :ok, serializer: API::CheckInsIndexSerializer
        else
            render json: @check_in.errors.full_messages, sattus: :unprocessable_entity
        end
    end
end

Here's my test:

RSpec.describe API::CheckInsController, type: :request do
    fit "should send if the client's location is World Wide" do
        program = create(:program, :with_client)
        worldwide = create(:location, name: "World Wide")
        program.client.update(location_id: worldwide.id)
        check_in = create(:check_in, client_id: program.client.id, program_id: program.id)
        create(:repositioning, check_in_id: check_in.id)
        create(:weigh_in, check_in_id: check_in.id)
        
        url = root_url[0..-2] + api_check_in_path(check_in.id) + "?sendReportCardEmail=true"

        put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }
        expect_any_instance_of(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
    end
end

and the error I see is:

 Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }
   Exactly one instance should have received the following message(s) but didn't: send_weekly_report_card_for_repositioning

What else do I need to do to ensure that function is called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰葑 2025-01-26 11:09:57

您正在以错误的顺序进行操作。您需要在预期调用该方法之前先设置期望:

expect_any_instance_of(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }

如果以后需要设置指示,则需要替换方法或对象间谍,如果您喜欢repand-act-assert(或当时给定),这很有用
结构测试的模式。

您还应注意,使用任何实例强烈劝阻您可以通过提供简单的类方法来避免它:

class WeeklyReportCardService
  def self.send_weekly_report_card_for_repositioning(...)
    new.send_weekly_report_card_for_repositioning(...)
  end
end
RSpec.describe API::CheckInsController, type: :request do
  it "should send if the client's location is World Wide" do
    expect(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
    put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }
  end
end

或者通过将WeeklyReportCardservice#New方法固定来返回模拟或间谍。

You're doing it in the wrong order. You need to set the expectation first before the method is expected to be called:

expect_any_instance_of(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }

If you need to set the expecations afterwards you need to replace the method or object with a spy which is useful if you prefer the arrange-act-assert (or given-when-then)
pattern for structuring tests.

You should also note that the use of any instance is strongly discouraged and you can avoid it by providing a simple class method:

class WeeklyReportCardService
  def self.send_weekly_report_card_for_repositioning(...)
    new.send_weekly_report_card_for_repositioning(...)
  end
end
RSpec.describe API::CheckInsController, type: :request do
  it "should send if the client's location is World Wide" do
    expect(WeeklyReportCardService).to receive(:send_weekly_report_card_for_repositioning)
    put url, params: { check_in: {type_of_weighin: 'standard'}}, headers: { "HTTP_AUTHENTICATION": @token }
  end
end

Or alternatively by stubbing the WeeklyReportCardService#new method to return a mock or spy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文