AssertContains on strings in jUnit
Asked Answered
E

12

256

Is there a nicer way to write in jUnit

String x = "foo bar";
Assert.assertTrue(x.contains("foo"));
Evangelistic answered 7/7, 2009 at 13:2 Comment(5)
IMO this is nice enough, suggested options are less readableRebellion
@TheGodfather less readable, but produce more meaningful assertion errors (ie, the accepted response will show the difference in strings, where as OPs solution will just show "False when expected True" on failure)Adjourn
What makes an assert "nicer" is the error message when it fails. How readable it is in the code is secondary to that, because you don't have to look at the code until it fails, and the failure message is the first thing you see.Djokjakarta
The question itself should be the accepted answer :DAbiogenetic
@Djokjakarta You can pass your own message as an argument to assertTrue, like Assert.assertTrue("Should contain substring 'foo'", x.contains("foo"));Robeson
J
381

If you add in Hamcrest and JUnit4, you could do:

String x = "foo bar";
Assert.assertThat(x, CoreMatchers.containsString("foo"));

With some static imports, it looks a lot better:

assertThat(x, containsString("foo"));

The static imports needed would be:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
Jasso answered 7/7, 2009 at 13:5 Comment(9)
Be sure you're using org.junit.Assert versus junit.framework.Assert, as the latter doesn't have the Hamcrest Matcher assertThat()Nierman
I think when running JUnit 4.10, the class to use is org.junit.matchers.JUnitMatchers, e.g.: assertThat("something", JUnitMatchers.containsString("some"));Otherwhere
The failure message for a failing assertThat is way more helpful then an assertTrueDeponent
static imports needed are import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.containsString; - just to save someone from troubleBrocky
... and org.hamcrest.Matchers.containsString; in the latest api, in the hamcrest-library dependency.Brocky
I faced 'cannot resolve method' issue too, but thanks to eis' comment above made the following changes. import org.hamcrest.Matchers; import static org.hamcrest.MatcherAssert.assertThat; assertThat(<string>, Matchers.containsString("<your string>"));Bund
org.hamcrest.CoreMatchers is not available but hamcrest-core.jar (1.3) is in the classpath. What can I do?Lais
@MarkusL, you can examine the JAR to find the correct package. I believe that it has changed since 2009.Jasso
For hamcrest-core 1.3 use this: org.hamcrest.core.StringContains.containsString( String )Lais
D
23

use fest assert 2.0 whenever possible EDIT: assertj may have more assertions (a fork)

assertThat(x).contains("foo");
Drumfish answered 8/12, 2012 at 12:5 Comment(2)
I did not find a contains method with AssertJ.assertThat. This is what I found instead - org.assertj.core.api.Assertions.assertThat(conversionException).hasMessageContaining("some substring");Ferula
sorry, I think my above comment does not suit to the context of this answer. I was on a different use case where I need to check for a substring within an exception message.Ferula
D
11

Use hamcrest Matcher containsString()

// Hamcrest assertion
assertThat(person.getName(), containsString("myName"));

// Error Message
java.lang.AssertionError:
Expected: a string containing "myName"
     got: "some other name"

You can optional add an even more detail error message.

// Hamcrest assertion with custom error message
assertThat("my error message", person.getName(), containsString("myName"));

// Error Message
java.lang.AssertionError: my error message
Expected: a string containing "myName"
     got: "some other name"

Posted my answer to a duplicate question here

Deponent answered 28/8, 2013 at 22:33 Comment(0)
R
10

You can use assertj-fluent assertions. It has lot of capabilities to write assertions in more human readable - user friendly manner.

In your case, it would be

 String x = "foo bar";
 assertThat(x).contains("foo");

It is not only for the strings, it can be used to assert lists, collections etc.. in a friendlier way

Rightism answered 21/10, 2020 at 14:56 Comment(0)
R
8

Example (junit version- 4.13)

import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;

public class TestStr {

@Test
public void testThatStringIsContained(){
    String testStr = "hi,i am a test string";
    assertThat(testStr).contains("test");
 }

}
Raeraeann answered 31/5, 2020 at 11:16 Comment(2)
This should be the accepted answer. Easiest and worksJobholder
Thanks @ajpieri.Raeraeann
A
5

Use the new assertThat syntax together with Hamcrest.

It is available starting with JUnit 4.4.

Antitrust answered 7/7, 2009 at 13:4 Comment(0)
H
5

It's too late, but just to update I got it done with below syntax

import org.hamcrest.core.StringContains;
import org.junit.Assert;

Assert.assertThat("this contains test", StringContains.containsString("test"));
Hypothalamus answered 15/7, 2019 at 4:30 Comment(0)
G
2

Another variant is

Assert.assertThat(actual, new Matches(expectedRegex));

Moreover in org.mockito.internal.matchers there are some other interesting matchers, like StartWith, Contains etc.

Guelph answered 13/5, 2016 at 13:53 Comment(0)
I
2

assertj variant

import org.assertj.core.api.Assertions;
Assertions.assertThat(actualStr).contains(subStr);
Impurity answered 27/5, 2020 at 7:42 Comment(0)
M
1

I wrote this utility method

public static void assertContains(String string, String subString) {
    Assertions.assertTrue(string.contains(subString));
}
Mcvay answered 14/11, 2022 at 8:8 Comment(0)
M
0

I've tried out many answers on this page, none really worked:

  • org.hamcrest.CoreMatchers.containsString does not compile, cannot resolve method.
  • JUnitMatchers.containsString is depricated (and refers to CoreMatchers.containsString).
  • org.hamcrest.Matchers.containsString: NoSuchMethodError

So instead of writing readable code, I decided to use the simple and workable approach mentioned in the question instead.

Hopefully another solution will come up.

Mathis answered 19/11, 2016 at 14:0 Comment(0)
T
0

The previous answers are fairly good if you are able and willing to add external libraries. For various reasons, this might not be the case. If you can't/don't want to add another dependency to your project, or if you just want to keep hamcrest at arms length, you could use the parts of hamcrest that come with JUnit.

For example, org.hamcrest.BaseMatcher and org.hamcrest.Matcher come with JUnit 4.10. One implementation could be:

public class StringMatchers {
    public static Matcher<String> contains(String expected) {
        return new BaseMatcher<String>() {
            @Override
            public boolean matches(Object actual) {
                String act = (String) actual;
                
                return act.contains(expected);
            }

            @Override
            public void describeTo(Description desc) {
                desc.appendText("should contain ").appendValue(expected);
            }
        };
    }
}

and then you can import it into other test files with import static <package>.StringMatchers.contains. This will leave you with the statement:

assertThat(x, contains(y));

PS. This is suspiciously similar to other libraries, so I would be surprised if they were implemented much different.

src: https://programmingideaswithjake.wordpress.com/2014/11/08/advanced-creation-of-hamcrest-matchers/ **not everything in here works!

Towland answered 15/9, 2022 at 21:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.