在 Ruby 单元测试中,如何断言字符串包含某个子字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16121190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:50:25  来源:igfitidea点击:

In Ruby unit tests, how to assert that a string contains certain substring?

ruby-on-railsrubystringunit-testing

提问by Louis Rhys

In a Ruby unit test, how do I assert that a string contains a substring? Something like:

在 Ruby 单元测试中,如何断言字符串包含子字符串?就像是:

assert_contains string_to_test, substring_to_verify

回答by Patrick Oscity

You could go with assert_match pattern, string, [message]which is true if string =~ pattern:

如果满足以下条件assert_match pattern, string, [message],您可以选择正确的方法string =~ pattern

assert_match substring_to_verify, string_to_test

e.g.

例如

assert_match /foo/, "foobar"

If you use this very often, why not write your own assertion?

如果您经常使用它,为什么不编写自己的断言呢?

require 'test/unit'

module Test::Unit::Assertions
  def assert_contains(expected_substring, string, *args)
    assert_match expected_substring, string, *args
  end
end

Alternatively, using the method described by @IvayloStrandjev (way easier to understand), you could define

或者,使用@IvayloStrandjev 描述的方法(更容易理解),您可以定义

require 'test/unit'

module Test::Unit::Assertions
  def assert_contains(expected_substring, string, *args)
    assert string.include?(expected_substring), *args
  end
end

The usage is exactly as you requested in your question, e.g.

用法与您在问题中要求的完全相同,例如

class TestSimpleNumber < Test::Unit::TestCase
  def test_something
    assert_contains 'foo', 'foobar'
  end

  def test_something_fails
    assert_contains 'x', 'foobar', 'Does not contain x'
  end
end

Which will produce

哪个会产生

Run options:

# Running tests:

.F

Finished tests in 0.000815s, 2453.9877 tests/s, 2453.9877 assertions/s.

  1) Failure:
test_something_fails(TestSimpleNumber) [assertion.rb:15]:
Does not contain x

2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

Edit

编辑

As requested, with automated message:

根据要求,带有自动消息:

module Test::Unit::Assertions
  def assert_contains(exp_substr, obj, msg=nil)
    msg = message(msg) { "Expected #{mu_pp obj} to contain #{mu_pp exp_substr}" }
    assert_respond_to obj, :include?
    assert obj.include?(exp_substr), msg
  end
end

adapted from the original assert_matchsource. This actually also works with Arrays!

改编自原始assert_match来源。这实际上也适用于数组!

assert_contains 3, [1,2,3]

回答by Ivaylo Strandjev

You can write assert string_to_test.include?(string_to_verify)for instance. You can not expect to have asserts for all the checks you would like to perform, so just go the the classic check of a boolean condition.

assert string_to_test.include?(string_to_verify)例如你可以写。您不能期望对要执行的所有检查进行断言,因此只需进行布尔条件的经典检查即可。

Also have a look hereto see a list of all available assertions.

另请查看此处以查看所有可用断言的列表。

回答by troelskn

There is assert_includes. Note that you have to reverse the order of expected/actual, relative to what would be intuitive:

assert_includes。请注意,相对于直观的顺序,您必须颠倒预期/实际的顺序:

result = 'foobar'
assert_includes 'foo', result

回答by the Tin Man

I'd use one of these:

我会使用其中之一:

assert(string_to_test[substring_to_verify])
assert_equal(substring_to_verify, string_to_test[substring_to_verify])

They accomplish the same thing so the first is my usual choice.

他们完成同样的事情,所以第一个是我通常的选择。

回答by knut

I would use assert_match:

我会用assert_match

require 'test/unit'

class MyTest < Test::Unit::TestCase
  def test_match
    assert_match( /aa/, 'xxaaxx')
  end
  def test_match_fail
    #~ assert_match( /aa/, 'xxbbxx')  #fails
  end
end

If you need it often, you could extend TestCase:

如果你经常需要它,你可以扩展 TestCase:

require 'test/unit'

module Test
  module Unit
    class TestCase
      #Define new assertion
      def assert_contains(string_to_test, substring_to_verify)
        assert_match( string_to_test, substring_to_verify)
      end
      def assert_not_contains(string_to_test, substring_to_verify)
        assert_not_match( string_to_test, substring_to_verify)
      end
    end
  end
end
class MyTest < Test::Unit::TestCase
  def test_contains()
    assert_contains( /aa/, 'xxaaxx')
    assert_contains( 'aa', 'xxaaxx')
  end
  #~ def test_contains_fail()
    #~ assert_contains( 'aa', 'xxxxxx')
    #~ assert_contains( /aa/, 'xxxxxx')
  #~ end
  #~ def test_contains_not_fail()
    #~ assert_not_contains( /aa/, 'xxaaxx')
    #~ assert_not_contains( 'aa', 'xxaaxx')
  #~ end
  def test_contains_not()
    assert_not_contains( 'aa', 'xxxxxx')
    assert_not_contains( /aa/, 'xxxxxx')
  end
  def test_contains_special_characters()
    assert_contains( '[aa', 'xx[aaxx')
    #~ assert_contains( /[aa/, 'xx[aaxx')
  end
end

Remarks:

评论:

  • When you use special regexp-characters (like []....) then you can use it in strings (at least my experiment in test_contains_special_charactersworked.
  • You can define your own regexps.
  • 当您使用特殊的正则表达式字符(如 []....)时,您可以在字符串中使用它(至少我的实验test_contains_special_characters有效。
  • 您可以定义自己的正则表达式。

回答by Whit Kemmey

Like this:

像这样:

assert string_to_test.index(substring_to_verify)

The .index method returns nil if the substring is not found, which will cause the assert to fail.

如果未找到子字符串,.index 方法将返回 nil,这将导致断言失败。