gpt4 book ai didi

ruby-on-rails - 从帮助器规范中 stub 一个帮助器方法

转载 作者:数据小太阳 更新时间:2023-10-29 07:08:30 25 4
gpt4 key购买 nike

我正在构建 Rails 应用程序并使用 RSpec 制定测试。

我为我正在创建的名为 current_link_to 的方法编写了测试。此方法应该检查当前页面是否对应于我传递给它的路径,并将 current 类添加到生成的链接中,以防它匹配。

这是规范:

require "spec_helper"

describe ApplicationHelper do
describe "#current_link_to" do
let(:name) { "Products" }
let(:path) { products_path }
let(:rendered) { current_link_to(name, path) }

context "when the given path is the current path" do
before { visit(path) }

it "should return a link with the current class" do
# Uses the gem "rspec-html-matchers" (https://github.com/kucaahbe/rspec-html-matchers)
expect(rendered).to have_tag("a", with: { href: path, class: "current" }) do
with_text(name)
end
end
end

context "when the given path is not the current path" do
before { visit(about_path) }

it "should return a link without the current class" do
expect(rendered).to have_tag("a", with: { href: path }, without: { class: "current" } ) do
with_text(name)
end
end
end
end
end

然后我尝试按照规范实现我的方法:

module ApplicationHelper
def current_link_to(name, path, options={})
options.merge!({ class: "#{options[:class]} current".strip }) if current_page?(path)

link_to(name, path, options)
end
end

但是,测试失败并出现以下错误:

Failure/Error: let(:rendered) { current_link_to(name, path) }

RuntimeError: You cannot use helpers that need to determine the current page unless your view context provides a Request object in a #request method

因为我真的不需要 current_page? 辅助方法来对请求执行检查,所以我决定将它 stub 是有意义的。

我尝试了以下方法,但均无效:

  1. helper.double(:current_page? => true)
    似乎 stub helper.current_page? 方法,但它与我的函数调用的方法不同。
  2. allow(ActionView::Helpers::UrlHelper).to receive(:current_page?).and_return(true)
    stub 似乎根本没有效果

在写这个问题时我偶然发现了解决方案。我设法在 before block 中使用它来 stub current_page? 方法:

allow(self).to receive(:current_page?).and_return(true)

它奏效了,但是这个解决方案提出的问题比它真正回答的要多。我现在对它是如何工作的感到困惑,因为 self 中看起来很奇怪>before block 将响应 current_page? 并且该方法实际上与我的助手正在调用的方法完全相同。

即使阅读了文档并试图通过使用 puts 调用来弄清楚它是如何工作的,以下疑虑仍然困扰着我:

  • 为什么在规范中直接提供辅助方法,当 the RSpec docs mention 时它们应该作为所有帮助程序规范中可用的 helper 对象的方法提供?
  • 在 RSpec before block 中对 self 设置 current_page? 方法如何以某种方式反射(reflect)到我的助手调用的实际方法上?我的助手中的 self 是否出于某种原因引用了您可以在 before block 中找到的相同 self ? RSpec 或 Rails 是否在幕后包含和混合了东西?
  • 如果相同的 self 包含我的规范和我的助手,那么在这种情况下 self 到底指的是什么?为什么到处都一样?

如果有人能帮我解决这个问题就太好了,因为这让我大吃一惊,而且我害怕使用我并不真正理解的代码。

最佳答案

恕我直言,您在这里测试的功能有点太多了。诀窍是只测试您需要测试的位。

在这种情况下,您只需要测试当前类是否在需要时添加,而不是在不需要时添加。

这段代码应该可以为您解决问题:

require 'rails_helper'

# Specs in this file have access to a helper object that includes
# the ApplicationHelper.
RSpec.describe ApplicationHelper, type: :helper do

describe 'current_link_to' do
let(:subject) { helper.current_link_to('some_name', 'some_path', options = {}) }

context 'where the path is current' do
before do
allow(helper).to receive(:current_page?).and_return true
end
it 'should include the current class' do
expect(subject).to match /current/
end
end

context 'where the path is not current' do
before do
allow(helper).to receive(:current_page?).and_return false
end
it 'should not include the current class' do
expect(subject).to_not match /current/
end
end
end
end

我有点油嘴滑舌,只测试了返回字符串中是否存在“current”。如果您想要更精确,可以测试类似“class="current"' 的内容。

另一个关键是页面顶部的注释,Rails 会为您将其插入到空白的帮助规范中:

# Specs in this file have access to a helper object that includes
# the ApplicationHelper.

这意味着您可以在上面的评论中使用“self”的地方使用“helper”,这让事情变得更清晰(恕我直言)

希望对您有所帮助!

关于ruby-on-rails - 从帮助器规范中 stub 一个帮助器方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21956762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com