How do I verify that code does not throw an exception in EK9?
← Error Handling and Exceptions · Ref: Q307
EK9 provides assertDoesNotThrow as a built-in keyword for verifying that an expression completes without throwing any exception. It is only valid inside @Test programs.
SYNTAX
assertDoesNotThrow(expression)
The test passes if the expression completes normally. The test fails if any exception is thrown.
USAGE
Use assertDoesNotThrow to verify no exception occurs:
assertDoesNotThrow(safeFunction())
If safeFunction() throws, the test fails with structured diagnostic output.
FAILURE OUTPUT
When assertDoesNotThrow fails, EK9 provides structured output:
assertDoesNotThrow FAILED Location: ./dev/tests.ek9:5:3 Expression: riskyFunction() Expected: No exception Actual: org.ek9.lang::Exception Message: Division by zero
The output includes the exception type and message, captured at compile time from the AST.
WHEN TO USE
assertDoesNotThrow is valuable when:
- Testing boundary conditions that should not throw (edge cases).
- Verifying error recovery leaves the system in a stable state.
- Testing that previously throwing code has been fixed.
- Documenting in tests that certain operations are safe.
ASSERTTHROWS VS ASSERTDOESNOTTHROW
assertThrows(ExceptionType, expr): Verifies an exception IS thrown. Can capture the exception.
assertDoesNotThrow(expr): Verifies NO exception is thrown.
Both are compile-time restricted to @Test programs.
See Q306 for assertThrows. See Q305 for require vs assert vs throw. See Q156 for basic assertions. See Q209 for exception testing patterns.
Example
#!ek9 defines module qa.errorhandling.assertdoesnot defines function <?- A safe division that returns Result instead of throwing. Used to demonstrate safe operations. -?> safeDivide() -> a as Integer b as Integer <- rtn as Integer: 0 if b == 0 throw Exception("Division by zero") rtn: a / b <?- Safe string processing that never throws. -?> processName() as pure -> name as String <- rtn as String: `Hello, ${name}!` defines program @Test AssertDoesNotThrowStatementTest() stdout <- Stdout() stdout.println("=== assertDoesNotThrow as statement ===") assertDoesNotThrow(processName("EK9")) stdout.println("Verified: processName does not throw") assertDoesNotThrow(safeDivide(10, 2)) stdout.println("Verified: safeDivide(10, 2) does not throw") @Test AssertDoesNotThrowMultipleTest() stdout <- Stdout() stdout.println("=== multiple assertDoesNotThrow checks ===") assertDoesNotThrow(processName("World")) stdout.println("Verified: processName(\"World\") is safe") assertDoesNotThrow(safeDivide(100, 5)) stdout.println("Verified: safeDivide(100, 5) is safe") assertDoesNotThrow(safeDivide(0, 1)) stdout.println("Verified: safeDivide(0, 1) is safe")
Common mistakes
E08091 — The parameter name is declared but never used in the function body. All parameters must be referenced. See ek9 -h E08091 for details.
Incorrect:
processName() as pure -> name as String <- rtn as String: "Hello!"
Correct:
processName() as pure -> name as String <- rtn as String: `Hello, ${name}!`
Other ways to ask this
- How does assertDoesNotThrow work in EK9?
- How do I test the happy path does not throw?
- What is the EK9 equivalent of JUnit assertDoesNotThrow?
Coming from another language?
Java: JUnit assertDoesNotThrow(() -> code) wraps Executable. Python: no built-in equivalent, just run the code and let pytest catch unexpected exceptions. Rust: no equivalent, tests fail on panic by default. Go: no equivalent, tests fail on unrecovered panic. Kotlin: assertDoesNotThrow { code } from kotlin.test. EK9: assertDoesNotThrow(expression) is a built-in keyword, compile-time restricted to @Test programs, with structured failure output including exception type and message.
Keywords: assertDoesNotThrow, catch, diagnostic, exception, handle, happy path, no throw, safe, test, testing, verify