Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExpectedException#expect() should take Matcher<? extends Throwable> as its argument #12

Open
UrsMetz opened this issue Jul 28, 2015 · 7 comments · May be fixed by #13
Open

ExpectedException#expect() should take Matcher<? extends Throwable> as its argument #12

UrsMetz opened this issue Jul 28, 2015 · 7 comments · May be fixed by #13

Comments

@UrsMetz
Copy link

UrsMetz commented Jul 28, 2015

This is a "re-post" of an issue originally opened at Junit: junit-team/junit4#610. As JUnit is going to depreciate and eventually remove ExpectedException I'm re-raising it hear in order to start a discussion whether this change should be made:

Consider the following test:

public class WrongUsageOfExpectedExceptionApi {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void wrongUsageOfExpectedExceptionApi() throws Exception {
        thrown.expect(RuntimeException.class);

        // thrown.expectMessage() should be used here
        // because an exception cannot start with a string
        thrown.expect(startsWith("some message"));
        throw new RuntimeException("some message");
    }
}
...

When you have something like this in a test it can be quite hard to figure out why the test fails.
At the moment ExpectedException#expect takes a Matcher<?> as its argument. By changing it to take only arguments of the type Matcher<? extends Throwable> the compiler could spot the mistake in the test given above.
I tried the code changes needed for the suggested change in the API with the current master (92a3f73) and all tests pass.
I understand that these changes break the API and non-generic Matchers won't work with the new signature of the method but is there any other reason not to have ExpectedException#expect only take arguments of the type Matcher<? extends Throwable>?
Apart from the exclusion of non-generic Matchers the only downside I see is that now you have to specify the generic type: That is you have to write for example

ExpectedException#expect(CoreMatchers.<Throwable>not(CoreMatchers.<Throwable>instanceOf(type)));

instead of

ExpectedException#expect(not(instanceOf(type)));
@UrsMetz
Copy link
Author

UrsMetz commented Jul 28, 2015

junit-team/junit4#1073 should also be considered when discussing this issue.

@npryce
Copy link
Contributor

npryce commented Jul 28, 2015

This is definitely an improvement.

The problem with instanceof and not(instanceof(...)) is that instanceof has the wrong signature, which will be fixed in Hamcrest eventually

@UrsMetz
Copy link
Author

UrsMetz commented Aug 20, 2015

@npryce Should I open a pull request with the suggested changes?
@tavianator Do you want to tackle the issue with ExpectedException.expectCause() you mentioned in junit-team/junit4#1073?

Considering the discussion in #11 and junit-team/junit4#1150: I'm not sure whether the changes would just be a small step in the "migration process" to having hamcrest-junit extend the "new" assertion-library-agnostic version of ExpectedException and whether those discussions should already be taking into consideration or postponed to a late point in time.

@tavianator
Copy link

@UrsMetz I'm happy to do that. But for similar reasons to that bug, I believe that expect() should take a Matcher<? super Throwable>, not a Matcher<? extends Throwable>.

@UrsMetz
Copy link
Author

UrsMetz commented Aug 20, 2015

I just had a look at the code of ExpectedException in hamcrest-java (should have done that before :-/; I thought it was identical to that from JUnit 4.12 but it is not): expectCause already takes a Matcher<? super Throwable>.
@npryce: As you changed expectCause to take a Matcher<? super Throwable> I guess the propossed pull request should also make expect take a Matcher<? super Throwable>?

@UrsMetz UrsMetz linked a pull request Sep 10, 2015 that will close this issue
@kcooney
Copy link

kcooney commented Dec 2, 2016

FYI: The JUnit team just updated ExpectedException.expectThrows() in JUnit to take in a Matcher<?> (it used to take Matcher<? extends Throwable> ).

@kcooney
Copy link

kcooney commented Dec 2, 2016

BTW, the title of this bug is wrong. You should mot modify expectThrows() to take in Matcher<? extends Throwable>, because that would prevent callers from using CoreMatchers.notNullValue(). It could be changed to Matcher<? super Throwable>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants