В тестах Ruby unit, как утверждать, что строка содержит определенную подстроку?

Как я могу утверждать, что строка содержит подстроку? Что-то вроде:

assert_contains string_to_test, substring_to_verify

Ответ 1

Вы можете assert_match pattern, string, [message] который является истинным, если string =~ pattern:

assert_match substring_to_verify, string_to_test

например

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

адаптированный из исходного источника assert_match. Это также работает с массивами!

assert_contains 3, [1,2,3]

Ответ 2

Например, вы можете написать assert string_to_test.include?(string_to_verify). Вы не можете рассчитывать на наличие утверждений для всех проверок, которые вы хотели бы выполнить, поэтому просто перейдите к классической проверке логического состояния.

Также посмотрите здесь, чтобы увидеть список всех доступных утверждений.

Ответ 3

Я бы использовал один из них:

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

Они выполняют одно и то же, поэтому первый - мой обычный выбор.

Ответ 4

Как это:

assert string_to_test.index(substring_to_verify)

Метод.index возвращает nil, если подстрока не найдена, что приведет к сбою assert.

Ответ 5

Я бы использовал 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 работал.
  • Вы можете определить собственные регулярные выражения.

Ответ 6

Существует assert_includes. Обратите внимание, что вам нужно отменить порядок ожидаемого/фактического, относительно того, что было бы интуитивно понятным:

result = 'foobar'
assert_includes 'foo', result