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

时间:2013-04-20 14:03:10

标签: ruby-on-rails ruby string unit-testing

在Ruby单元测试中,如何断言字符串包含子字符串?类似的东西:

assert_contains string_to_test, substring_to_verify

6 个答案:

答案 0 :(得分:32)

您可以使用assert_match pattern, string, [message],如果string =~ pattern

,则为真
assert_match substring_to_verify, string_to_test

e.g。

assert_match /foo/, "foobar"

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

require 'test/unit'

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

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

require 'test/unit'

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

用法完全按照您在问题中的要求使用,例如

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

哪个会产生

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

修改

根据要求,使用自动消息:

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

改编自the original assert_match source。这实际上也适用于Arrays!

assert_contains 3, [1,2,3]

答案 1 :(得分:7)

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

还要查看here以查看所有可用断言的列表。

答案 2 :(得分:3)

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

result = 'foobar'
assert_includes 'foo', result

答案 3 :(得分:2)

我会使用其中一种:

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

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

答案 4 :(得分:0)

像这样:

assert string_to_test.index(substring_to_verify)

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

答案 5 :(得分:0)

我会使用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

如果您经常需要,可以扩展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

说明:

  • 当你使用特殊的正则表达式字符(如[] ....)时,你可以在字符串中使用它(至少我在test_contains_special_characters的实验工作。
  • 您可以定义自己的正则表达式。