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

Include assertThrows into core api #621

Open
changusmc opened this issue Sep 3, 2019 · 7 comments
Open

Include assertThrows into core api #621

changusmc opened this issue Sep 3, 2019 · 7 comments
Labels
P3 not scheduled type=addition A new feature

Comments

@changusmc
Copy link

We'd like to use this code aosp-mirror/platform_frameworks_support@bf04c31#diff-46afb720089a0149afb46f71274f5642 from our Kotlin tests, can you please include it into Truth?

We could just add it to one of our internal libraries and use it. However, seeing as this code is being duplicated on many repos on GitHub: https://github.com/search?l=Kotlin&p=2&q=ThrowableSubject&type=Code, it might make sense to include it in Truth.

@cgruber
Copy link
Contributor

cgruber commented Sep 3, 2019

Just piping up to point out that this is slightly different than previous discussions about assertThrows() insofar as (a) 4.13 isn't released, despite it having betas and being internally used in Google, so not everyone will have assertThrows from JUnit handy in their deps, (b) I've now seen several cases of people including a dep on kotlin.test exclusively for assertFailsWith<SomeErrorType> { lambda logic } while using Truth for everything else.

While I think it kind of made sense before when we were certain everyone would have this (or equivalent) function in their deps, I don't think that's a sound assumption under present conditions.

(Trying to head off objections that I've already heard inside Google to related inquiries, since I think we're in a different situation than that in which those discussions occurred)

@kluever kluever added P2 has an ETA type=addition A new feature labels Sep 4, 2019
@kluever
Copy link
Member

kluever commented Sep 4, 2019

/cc @cushon @cpovirk @lowasser

@cushon
Copy link
Contributor

cushon commented Sep 4, 2019

related: b/114409026

@JakeWharton
Copy link

The linked API is notably different (and more usable, not that I'm biased as its author) than JUnit and kotlin.test.

In Kotlin, for JUnit, you have to use assertThrows(IllegalStateException::class.java) { .. } whereas this function requires only assertThrows<IllegalStateException> { .. }. Having to specify ::class.java isn't going to kill anyone, but it's visual clutter. kotlin.test gets to share the same nice syntax.

Beyond that, the other APIs immediately fall short. JUnit lets you assert on the exact message but nothing like start/end/regex-based matching. For that, you need to change how you assert by capturing the return value and asserting on the message or wrapping in a ThrowableSubject and then asserting.

Similarly, any causal analysis requires capturing the Throwable, wrapping, and then analyzing.

The above snippet returns the ThrowableSubject directly which lets you immediately chain into any of these more advanced assertions, or combine them in an apply block.

assertThrows<IllegalStateException> {
  ...
}.apply {
  hasMessage().startsWith("Whatever: ")
  hasCause().isInstanceOf(SomeException::class.java)
}

@cgruber
Copy link
Contributor

cgruber commented Sep 4, 2019

I really do like @JakeWharton's variant, but I'm not sure if this can be achieved from within Java, so there are a few things questions this forces.

  1. is it time to start letting kotlin into Truth.
    1. if so, is it reasonable to make two flavors, one of which uses reified types and the other
      of which passes a class object, so Java users can still use it?
  2. if not, is it reasonable to make a truth-kotlin extension project?
    1. if so then should we put a Java variant that takes Class like assertThrows(Class) in the main
      project?

Personally I'd love to see Jake's flavor, but we also have a lot of Java left.

@cpovirk cpovirk added P3 not scheduled and removed P2 has an ETA labels Jan 13, 2020
@Marcono1234
Copy link

Is this issue here about Kotlin only? From the title of this issue it sounds to be generic, but the comments here seem to be mostly / only about Kotlin.

Even for Java projects a Truth assertThrows method would be useful:

  • Returning ThrowableSubject to allow directly performing assertions on the exception
  • Benefiting from Truth's Stack Trace Cleaner

Maybe it would also be useful to have two flavors: One assertThrows which checks if the exception class is equal, and another one which checks if the class is an instanceof.

@mrj
Copy link

mrj commented Jun 7, 2023

Yes, I'm not keen to add a JUnit dependency just for assertThrows, especially since I'm making my Jar distribution self-test when run, so the testing frameworks are inside it.

I'm currently using (Java):

try {
    [Manipulate object "o"]
    assertWithMessage("Manipulating %s should have thrown an UnsupportedOperationException", o).fail();
} catch (UnsupportedOperationException expected) {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 not scheduled type=addition A new feature
Projects
None yet
Development

No branches or pull requests

8 participants