Search code examples
javajunitjunit4hamcrest

Writing better JUnit Parameterized test cases


I have an interesting requirement. I want to have as better test case coverage as possible in my application. I am using Parameterized Junit to run testcases with number of different inputs. My sample test class looks like this:

@Parameters
public static Collection<Object[]> testInputs()
{
    return Arrays.asList({
        {1, CoreMatchers.is(1)},
        {2, CoreMatchers.is(2)}
    });
}
@Test
public test()
{
    myApp.run(); 
    assertThat(myApp.getA(), matcher);
}

This way, I defined the assertion logic with my test parameters. Now I want to run multiple matchers on the test case, some of them can be custom matchers which I wrote.

@Parameters
public static Collection<Object[]> testInputs()
{
    return Arrays.asList({
        {1, Arrays.asList( CoreMatchers.is(1), CustomMatchers.status(1) ) },
        {2, Arrays.asList( CoreMatchers.is(2), CustomMatchers.status(2) ) }
    });
}

And assertion is like:

for(Matcher<MyApp> matcher: matchers)
{
    assertThat(myApp, matcher);
}

But the problem is, both the matchers run on different objects. What is the best way I can define my CustomMatcher ??

Should I categorize the assertion by type of matcher?

I would appreciate any help. Thanks in advance.


Solution

  • I'm not sure what you mean by "both the matchers run on different objects," but you can combine the matchers for a single test run using CoreMatchers.allOf. This way you don't need to loop over a list of matchers and can pass any number of matchers, including one.

    @Parameters
    public static Collection<Object[]> testInputs()
    {
        return Arrays.asList({
            {1, CoreMatchers.allOf( CoreMatchers.is(1), CustomMatchers.status(1) ) },
            {2, CoreMatchers.allOf( CoreMatchers.is(2), CustomMatchers.status(2) ) }
        });
    }