In Ruby unit tests, how to assert that a string contains certain substring?
You could go with assert_match pattern, string, [message]
which is true if 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 endend
Alternatively, using the method described by @IvayloStrandjev (way easier to understand), you could define
require 'test/unit'module Test::Unit::Assertions def assert_contains(expected_substring, string, *args) assert string.include?(expected_substring), *args endend
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' endend
Which will produce
Run options:# Running tests:.FFinished tests in 0.000815s, 2453.9877 tests/s, 2453.9877 assertions/s. 1) Failure:test_something_fails(TestSimpleNumber) [assertion.rb:15]:Does not contain x2 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 endend
adapted from the original assert_match
source. This actually also works with Arrays!
assert_contains 3, [1,2,3]
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.
Also have a look here to see a list of all available assertions.
There is assert_includes
:
assert_includes 'foobar', 'foo'
will assert that foobar
contains foo
.