122 lines
3.1 KiB
Markdown
122 lines
3.1 KiB
Markdown
# Testing and Assertions
|
|
|
|
Lyng provides several built-in functions for testing and verifying code behavior. These are available in all scripts.
|
|
|
|
## Basic Assertions
|
|
|
|
### `assert`
|
|
|
|
Assert that a condition is true.
|
|
|
|
assert(condition, message=null)
|
|
|
|
- `condition`: A boolean expression.
|
|
- `message` (optional): A string message to include in the exception if the assertion fails.
|
|
|
|
If the condition is false, it throws an `AssertionFailedException`.
|
|
|
|
```lyng
|
|
assert(1 + 1 == 2)
|
|
assert(true, "This should be true")
|
|
```
|
|
|
|
### `assertEquals` and `assertEqual`
|
|
|
|
Assert that two values are equal. `assertEqual` is an alias for `assertEquals`.
|
|
|
|
assertEquals(expected, actual)
|
|
assertEqual(expected, actual)
|
|
|
|
If `expected != actual`, it throws an `AssertionFailedException` with a message showing both values.
|
|
|
|
```lyng
|
|
assertEquals(4, 2 * 2)
|
|
assertEqual("hello", "hel" + "lo")
|
|
```
|
|
|
|
### `assertNotEquals`
|
|
|
|
Assert that two values are not equal.
|
|
|
|
assertNotEquals(unexpected, actual)
|
|
|
|
If `unexpected == actual`, it throws an `AssertionFailedException`.
|
|
|
|
```lyng
|
|
assertNotEquals(5, 2 * 2)
|
|
```
|
|
|
|
## Exception Testing
|
|
|
|
### `assertThrows`
|
|
|
|
Assert that a block of code throws an exception.
|
|
|
|
assertThrows(code)
|
|
assertThrows(expectedExceptionClass, code)
|
|
|
|
- `expectedExceptionClass` (optional): The class of the exception that is expected to be thrown.
|
|
- `code`: A lambda block or statement to execute.
|
|
|
|
If the code does not throw an exception, an `AssertionFailedException` is raised.
|
|
If an `expectedExceptionClass` is provided, the thrown exception must be of that class (or its subclass), otherwise an error is raised.
|
|
|
|
`assertThrows` returns the caught exception object if successful.
|
|
|
|
```lyng
|
|
// Just assert that something is thrown
|
|
assertThrows { 1 / 0 }
|
|
|
|
// Assert that a specific exception class is thrown
|
|
assertThrows(NoSuchElementException) {
|
|
[1, 2, 3].findFirst { it > 10 }
|
|
}
|
|
|
|
// You can use the returned exception
|
|
val ex = assertThrows { throw Exception("custom error") }
|
|
assertEquals("custom error", ex.message)
|
|
```
|
|
|
|
## Other Validation Functions
|
|
|
|
While not strictly for testing, these functions help in defensive programming:
|
|
|
|
### `require`
|
|
|
|
require(condition, message="requirement not met")
|
|
|
|
Throws an `IllegalArgumentException` if the condition is false. Use this for validating function arguments.
|
|
|
|
If we want to evaluate the message lazily:
|
|
|
|
require(condition) { "requirement not met: %s"(someData) }
|
|
|
|
In this case, formatting will only occur if the condition is not met.
|
|
|
|
### `check`
|
|
|
|
check(condition, message="check failed")
|
|
|
|
Throws an `IllegalStateException` if the condition is false. Use this for validating internal state.
|
|
|
|
With lazy message evaluation:
|
|
|
|
check(condition) { "check failed: %s"(someData) }
|
|
|
|
In this case, formatting will only occur if the condition is not met.
|
|
|
|
### TODO
|
|
|
|
It is easy to mark some code and make it throw a special exception at cone with:
|
|
|
|
TODO()
|
|
|
|
or
|
|
|
|
TODO("some message")
|
|
|
|
It raises an `NotImplementedException` with the given message. You can catch it
|
|
as any other exception when necessary.
|
|
|
|
Many IDE and editors have built-in support for marking code with TODOs.
|