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