1

我想为 Rspec 2 声明自定义匹配器

我正在使用rspec 2.13rails 3.2.13

我试图写这样的东西:

RSpec::Matchers.define :be_present do |expected|
  match do
    expected !be_empty
  end
end

但是当我在规范中使用它时,它不起作用失败:

  1) NewsletterMailer.send_newsletter_to_groups from 
     Failure/Error: its(:from) { should be_present }
     ArgumentError:
       wrong number of arguments (1 for 0)

规格代码:

describe NewsletterMailer do

  describe '.send_newsletter_to_emails' do
    let(:user) { create(:admin) }
    let(:user2) { create(:user) }
    subject { NewsletterMailer.send_newsletter_to_emails(newsletter.id, "#{user.email}, #{user2.email}") }

    its(:to) { should == [user.email, user2.email] }
    its(:from) { should be_present }
    its(:subject) { should be }
  end

编辑:

我想要这样的逻辑反转:

its(:from) { should_not be_nil }
4

2 回答 2

2

我不确定你为什么在这里需要一个自定义匹配器。不会

its(:from) { should be }

为你工作?

见这里: https ://www.relishapp.com/rspec/rspec-expectations/v/2-3/docs/built-in-matchers/be-matchers#be-matcher

obj.should be # passes if obj is not nil

更新:

由于显然问题是如何为现有的 predicate 编写自定义匹配器present?,那么答案是:rspec 已经提供了,并且仍然不需要编写自定义匹配器。

https://www.relishapp.com/rspec/rspec-expectations/v/2-3/docs/built-in-matchers/predicate-matchers

对于对象上的任何谓词#foo?,您只需编写should be_foo. Rspec 甚至会使用更自然的语法为以“has”开头的谓词定义匹配器has_foo?,这样您就可以编写should have_foo.

于 2013-05-30T17:17:10.743 回答
2

解决方案:

RSpec::Matchers.define :be_present do |expected|
  match do |actual|
    actual && actual.present?
  end
end

看起来这个助手已经存在于 Rspec 中。

我只是重新发明了轮子。但我仍然会让这个答案,不要删除这个帖子。

这将是开发人员的提示,如何在没有参数的情况下声明自定义匹配器,例如。

be_something_special

于 2013-05-30T16:25:39.000 回答