Skip to content

Commit

Permalink
Fixed various PR comments
Browse files Browse the repository at this point in the history
This PR fixes various comments,

1. added cross ref to "Third-party Assertion Libraries"
2. wrapped lines to 90 char
3. made the anchors hierarchical
4. added note for assertJ's no-exception assertion
5. used static imports for Assertions
6. created separate sections for assertThrows and assertThrowsExactly
7. explicitly mentioned that explicitly mention that a throws clause has no effect.

Solves Issue: junit-team#3730

---

I hereby agree to the terms of the JUnit Contributor License Agreement.
  • Loading branch information
Driptaroop Das committed Apr 17, 2024
1 parent f13cbcd commit 45de756
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 20 deletions.
80 changes: 70 additions & 10 deletions documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -370,37 +370,97 @@ as a failure.
[[writing-tests-exceptions]]
=== Exception Handling

JUnit Jupiter provides robust support for handling test exceptions. This includes the built-in mechanisms for managing test failures due to exceptions, the role of exceptions in implementing assertions, and how to specifically assert non-throwing conditions in code.
JUnit Jupiter provides robust support for handling test exceptions. This includes the
built-in mechanisms for managing test failures due to exceptions, the role of exceptions
in implementing assertions, and how to specifically assert non-throwing conditions in code.

[[writing-tests-uncaught-exceptions]]
[[writing-tests-exceptions-uncaught]]
==== Uncaught Exceptions and Test Failures

In JUnit Jupiter, if an exception is thrown and not caught within the test method, the framework will mark the test as failed.
In JUnit Jupiter, if an exception is thrown and not caught within the test method, the
framework will mark the test as failed.

[source,java,indent=0]
----
include::{testDir}/example/exception/UncaughtExceptionHandlingDemoTestCase.java[tags=user_guide]
----

In the above example, the `testThatFailsDueToUncaughtException` method throws a `RuntimeException`. Since the exception is not caught within the test method, JUnit Jupiter will automatically fail the test.
In the above example, the `testThatFailsDueToUncaughtException` method throws a
`RuntimeException`. Since the exception is not caught within the test method, JUnit
Jupiter will automatically fail the test.

[[writing-tests-assertions-using-exceptions]]
NOTE: It's important to clarify that specifying a `throws` clause in the test method
has no effect on the outcome of the test. JUnit Jupiter does not interpret it as
an expectation or assertion about what exceptions the test method should throw. A test
fails only if an exception is thrown unexpectedly or if an assertion fails.

[[writing-tests-exceptions-assertions]]
==== Assertions Using Exceptions

Assertions in JUnit Jupiter are implemented using exceptions. The framework provides a set of assertion methods in the `org.junit.jupiter.api.Assertions` class, which throw `AssertionError` when an assertion fails. This mechanism is a core aspect of how JUnit handles assertion failures as exceptions.
Assertions in JUnit Jupiter are implemented using exceptions. The framework provides
a set of assertion methods in the `org.junit.jupiter.api.Assertions` class, which throw
`AssertionError` when an assertion fails. This mechanism is a core aspect of how JUnit
handles assertion failures as exceptions.

NOTE: This failed assertion behaviour (i.e. throwing `AssertionError`) may be different
for third party assertion libraries. See also: <<writing-tests-assertions-third-party>>.

NOTE: JUnit Jupiter itself does not differentiate between failed assertions
(`AssertionError`) and other types of exceptions. All uncaught exceptions lead to a test
failure. However, Integrated Development Environments (IDEs) and other tools may
distinguish between these two types of failures by checking whether the thrown exception
is an instance of `AssertionError`.

NOTE: JUnit Jupiter itself does not differentiate between failed assertions (`AssertionError`) and other types of exceptions. All uncaught exceptions lead to a test failure. However, Integrated Development Environments (IDEs) and other tools may distinguish between these two types of failures by checking whether the thrown exception is an instance of AssertionError.
[[writing-tests-exceptions-expected]]
==== Asserting Expected Exception Conditions

[[writing-tests-assertions-using-assertDoesNotThrow]]
==== Asserting Non-Exception Conditions with `assertDoesNotThrow`
JUnit Jupiter offers specialized assertions for testing that specific exceptions are
thrown under expected conditions. The `assertThrows` and `assertThrowsExactly` assertions
are critical tools for validating that your code responds correctly to error conditions
by throwing the appropriate exceptions.

Although any exception thrown from a test method will cause the test to fail, there are certain use cases where it can be beneficial to explicitly assert that an exception is not thrown for a given code block within a test method. The `assertDoesNotThrow` assertion can be used when you want to verify that a particular piece of code does not throw any exceptions.
[[writing-tests-exceptions-expected-assertThrows]]
===== Using `assertThrows`

The `assertThrows` method is used to verify that a particular type of exception is thrown
during the execution of a provided executable block. It not only checks for the type of
the thrown exception but also its subclasses, making it suitable for more generalized
exception handling tests.

[source,java,indent=0]
----
include::{testDir}/example/exception/ExceptionAssertionDemoTestCase.java[tags=user_guide]
----

[[writing-tests-exceptions-expected-assertThrowsExactly]]
===== Using `assertThrowsExactly`

`assertThrowsExactly` is used when you need to assert that an exception is not only
thrown but is exactly of a specific type, not allowing for subclasses of the exception.
This is useful when precise exception handling behavior needs to be validated.

[source,java,indent=0]
----
include::{testDir}/example/exception/ExceptionAssertionExactDemoTestCase.java[tags=user_guide]
----

[[writing-tests-exceptions-using-assertDoesNotThrow]]
==== Using `assertDoesNotThrow` to Verify Absence of Exceptions

Although any exception thrown from a test method will cause the test to fail, there are
certain use cases where it can be beneficial to explicitly assert that an exception is
not thrown for a given code block within a test method. The `assertDoesNotThrow`
assertion can be used when you want to verify that a particular piece of code does not
throw any exceptions.

[source,java,indent=0]
----
include::{testDir}/example/exception/AssertDoesNotThrowExceptionDemoTestCase.java[tags=user_guide]
----

NOTE: Other third party assertion libraries also provide similar support. For example,
`AssertJ` has `assertThatNoException().isThrownBy(() -> ...)`. See also: <<writing-tests-assertions-third-party>>.

[[writing-tests-disabling]]
=== Disabling Tests

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,22 @@

package example.exception;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

// @formatter:off
// tag::user_guide[]

class AssertDoesNotThrowExceptionDemoTestCase {

@Test
void assertDoesNotThrowExceptionTest() {
Assertions.assertThrows(RuntimeException.class, () -> {
failsDueToException();
Assertions.assertDoesNotThrow(() -> {
shouldNotThrowException();
});
assertDoesNotThrow(() -> {
shouldNotThrowException();
});
}

void failsDueToException(){
throw new RuntimeException();
}

void shouldNotThrowException(){}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package example.exception;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertThrows;

// @formatter:off
// tag::user_guide[]

class ExceptionAssertionDemoTestCase {
@Test
void testExpectedExceptionIsThrown() {
assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Expected exception");
}, "Expected IllegalArgumentException to be thrown");

assertThrows(RuntimeException.class, () -> {
throw new IllegalArgumentException("Expected exception");
}, "should also pass because IllegalArgumentException is subclass of RuntimeException");
}
}

// end::user_guide[]
// @formatter:on
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package example.exception;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertThrowsExactly;

// @formatter:off
// tag::user_guide[]

public class ExceptionAssertionExactDemoTestCase {
@Test
void testExpectedExceptionIsThrown() {
assertThrowsExactly(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Expected exception");
}, "This will fail because because we expect IllegalArgumentException to be thrown");

assertThrowsExactly(RuntimeException.class, () -> {
throw new IllegalArgumentException("Expected exception");
}, "This will fail because expected exactly RuntimeException to be thrown, not subclasses");
}
}

// end::user_guide[]
// @formatter:on

0 comments on commit 45de756

Please sign in to comment.