Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Minitest规范自定义匹配器_Ruby_Minitest - Fatal编程技术网

Ruby Minitest规范自定义匹配器

Ruby Minitest规范自定义匹配器,ruby,minitest,Ruby,Minitest,我的测试中有一句话: page.has_reply?("my reply").must_equal true 为了使其更具可读性,我想使用自定义匹配器: page.must_have_reply "my reply" 基于的文档,我希望我需要编写一个匹配器,它看起来像这样: def have_reply(text) subject.has_css?('.comment_body', :text => text) end MiniTest::Unit::TestCase.regist

我的测试中有一句话:

page.has_reply?("my reply").must_equal true
为了使其更具可读性,我想使用自定义匹配器:

page.must_have_reply "my reply"
基于的文档,我希望我需要编写一个匹配器,它看起来像这样:

def have_reply(text)
  subject.has_css?('.comment_body', :text => text)
end
MiniTest::Unit::TestCase.register_matcher :have_reply, :have_reply

问题是我看不到如何获取对主题(即页面对象)的引用。文档中说“Note subject必须是断言中的第一个参数”,但这并没有真正的帮助。

有一个小例子,您可以创建一个类,该类应该响应一组方法
匹配?
失败消息\u for u should
失败消息\u for u should\u not
。 在
匹配?
方法中,您可以获得对主题的引用

class MyMatcher
  def initialize(text)
    @text = text
  end

  def matches? subject
    subject =~ /^#{@text}.*/
  end

  def failure_message_for_should
    "expected to start with #{@text}"
  end

  def failure_message_for_should_not
    "expected not to start with #{@text}"
  end
end

def start_with(text)
  MyMatcher.new(text)
end
MiniTest::Unit::TestCase.register_matcher :start_with, :start_with

describe 'something' do
  it 'must start with...' do
    page = 'my reply'
    page.must_start_with 'my reply'
    page.must_start_with 'my '
  end
end

有很多方法可以在这里得到你想要的。最简单的方法是根本不要弄乱断言、期望或匹配器,而只使用断言。因此,假设您已经定义了
has\u reply?
方法,您可以使用以下方法:

assert page.has_reply?("my reply")
但是,这并不能让你得到你所要求的
必须有答复
语法。我怀疑你真的有一个
has\u reply?
方法。那么,让我们开始吧

您的问题是“如何获取对主题(即页面对象)的引用”。在这种情况下,subject是
必须具有的对象\u reply
方法是在其上定义的。因此,您应该使用
this
而不是
subject
。但这并没有那么简单。匹配者添加了一个我们通常断言(
断言相等
反驳相等
)或期望(
必须相等
不会相等)所没有的间接层次。如果要编写匹配器,需要实现匹配器API

幸运的是,您实际上不必实现API。由于您似乎已经打算依赖Cabybara的have_css
matcher,我们可以简单地使用Capybara的HaveSelector类,让它实现适当的API。我们只需要使用返回HaveSelector对象的方法创建自己的Matchers模块

# Require Minitest Matchers to make this all work
require "minitest/matchers"
# Require Capybara's matchers so you can use them
require "capybara/rspec/matchers"

# Create your own matchers module
module YourApp
  module Matchers
    def have_reply text
      # Return a properly configured HaveSelector instance
      Capybara::RSpecMatchers::HaveSelector.new(:css, ".comment_body", :text => text)
    end

    # Register module using minitest-matcher syntax
    def self.included base
      instance_methods.each do |name|
        base.register_matcher name, name
      end
    end
  end
end
然后,在
minitest\u helper.rb
文件中,您可以包含Matchers模块,以便使用它。(此代码将在所有测试中包括匹配器。)

小型火柴手完成所有的艰苦工作。您现在可以使用matcher作为断言:

def test_using_an_assertion
  visit root_path
  assert_have_reply page, "my reply"
end
或者,您可以使用matcher作为期望:

it "is an expectation" do
  visit root_path
  page.must_have_reply "my reply"
end
最后,您可以将其用于主题:

describe "with a subject" do
  before  { visit root_path }
  subject { page }

  it { must have_reply("my reply") }
  must { have_reply "my reply" }
end
重要信息:要使其正常工作,您必须使用“gem minitest matchers”,即“>=1.2.0”,因为该gem的早期版本中未定义寄存器匹配器

describe "with a subject" do
  before  { visit root_path }
  subject { page }

  it { must have_reply("my reply") }
  must { have_reply "my reply" }
end