question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

shouldNotThrow and shouldNotThrowAny matchers

See original GitHub issue

Having these matchers would be great -shouldNotThrow -shouldNotThrowAny

Currently there is not way of expressing that easily with kotlintest matchers

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:30 (24 by maintainers)

github_iconTop GitHub Comments

4reactions
TAGCcommented, Nov 8, 2018

@TAGC Would you mind creating an issue for that? I agree with you that syntax would be prettier and human-readable.

Not sure what you mean. Why create a new issue for the same proposal as this one?

What’s the difference except more noise ?

In short test-cases, it probably does create more noise than it’s worth. For example, in my case instead of:

it("can be connected to other ports of a supertype") {
    val derivedPort = createDummy<Derived>()
    val basePort = createDummy<Base>()
    derivedPort join basePort
}

I might write:

it("can be connected to other ports of a supertype") {
    val derivedPort = createDummy<Derived>()
    val basePort = createDummy<Base>()
    shouldNotThrow { derivedPort join basePort }
}

And it wouldn’t make much difference.

However, in longer test-cases the advantage is that it helps distinguish the assertion from the rest of the setup/cleanup code.

it("verifies something") {
    val x = Foo()
    x.bar()
    x.baz()
    // More setup for x
    
    val y = Foo2()
    y.bar(x)
    y.baz(x)
    // More setup for y
    
    y.baz(z)
    
    cleanup(x)
    cleanup(y)
    // More cleanup
}

vs.

it("verifies something") {
    val x = Foo()
    x.bar()
    x.baz()
    // More setup for x

    val y = Foo2()
    y.bar(x)
    y.baz(x)
    // More setup for y

    shouldNotThrow { y.baz(z) }

    cleanup(x)
    cleanup(y)
    // More cleanup
}

Without this assertion, I might be inclined to write y.baz(z) // should not throw, but that’s not as good for the reason why comments in general are not preferable to readable code: because comments can become stale, they can lie, but code never lies.

Furthermore, if you just write the assertion as a plain statement and it fails, all you get is a regular stacktrace associated with the unit test, indistinguishable in structure from the stacktraces you’d get if any other part of the test (setup/cleanup) failed. A failed shouldNotThrow assertion can instead capture exceptions and rethrow them with a message like “Expected no exception to be thrown, but <wrapped exception> was thrown”.

In the same way that the shouldNotThrow statement helps visually distinguish the assertion code from the rest of test code (making the test more readable), the exception it throws can help distinguish an assertion failure from any other failure within the code (making the problem easier to understand and the bug easier to fix).

It’s an especially nice assertion to have when you have some function that should throw exceptions under certain circumstances and shouldn’t throw in others, and you want test both types of scenarios. That leads to nice symmetrical code:

public void Message_Decoder_Should_Decode_Additional_Messages_After_Decoding_Complete_And_After_Reset()
{
    // GIVEN a mock decoder that is able to decode messages and has completed decoding.
    var mockDecoder = new MockMessageDecoder
    {
        DecodingMessagesAllowed = true
    };
    mockDecoder.SetDecodingComplete();

    // WHEN we reset the mock decoder.
    mockDecoder.Reset();

    // THEN we should be able to decode more messages.
    Should.NotThrow(() => mockDecoder.DecodeMessage(default(GenericMessage)));
}

[Fact]
public void Message_Decoder_Should_Decode_No_Additional_Messages_After_Decoding_Complete_And_Before_Reset()
{
    // GIVEN a mock decoder that can decode messages.
    var mockDecoder = new MockMessageDecoder
    {
        DecodingMessagesAllowed = true
    };

    // WHEN decoding is complete.
    mockDecoder.SetDecodingComplete();

    // THEN an exception should be thrown when trying to decode another message.
    Should.Throw<InvalidOperationException>(() => mockDecoder.DecodeMessage(default(GenericMessage)));
}
1reaction
LeoColmancommented, Nov 2, 2018

@sksamuel Sometimes users want to write things in a more explicitly.

It’s the same reason we added the matchers shouldNotBeTrue and shouldNotBeFalse https://github.com/kotlintest/kotlintest/issues/452

Of course (3 ==3).shouldBeTrue is exactly the same as (3==3).shouldNotBeFalse, but sometimes one might want to say in a way or another.

Adding a shouldNotThrow empty block doesn’t look like a problem to me, and it won’t make users more confused

Read more comments on GitHub >

github_iconTop Results From Across the Web

shouldNotThrow and shouldNotThrowAny matchers · Issue #205
Having these matchers would be great -shouldNotThrow -shouldNotThrowAny Currently there is not way of expressing that easily with kotlintest ...
Read more >
Exceptions - Kotest
val exception = shouldThrowAny { // test here can throw any type of Throwable! } Edit this page · Previous. Data Class Matchers....
Read more >
Exceptions Rule Set | Detekt
... configuration to change the list of functions which should not throw any exceptions. ... ignores too generic exception types which match this...
Read more >
Using the "should NOT produce [exception]" syntax in ScalaTest
Either it should throw a particular exception or it should not throw any exception. What you're saying is you want to assert that...
Read more >
Using matchers - ScalaTest
You can alternatively import the members of the trait, a technique particularly useful when you want to try out matcher expressions in the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found