> For the complete documentation index, see [llms.txt](https://docs.konsist.lemonappdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.konsist.lemonappdev.com/writing-tests/declaration-assert.md).

# Declaration Assertion

Verify codebase using Konsist API

Assertions are used to perform code base verification. This is the final step of Konsist verification preceded by scope creation ([Create The Scope](/writing-tests/koscope.md)) and [Declaration Filtering](/writing-tests/declaration-query-and-filter.md) steps:

```mermaid
%%{init: {'theme':'forest'}}%%
flowchart TB
    Step1["1. Create The Scope"]-->Step2
    Step2["2. Filter Declarations"]-->Step3
    Step3["3. Define Assertion"]
    style Step3 fill:#52B523,stroke:#666,stroke-width:2px,color:#fff
```

## Assertion Methods

Konsist offers a variety of assertion methods. These can be applied to a list of KoDeclarations as well as a single declaration.

### Assert True

In the below snippet, the assertion (performed on the list of interfaces) verifies if every interface has a `public` visibility modifier.

```kotlin
koScope
    .interfaces()
    .assertTrue { it.hasPublicModifier }
```

The `it` parameter inside the `assertTrue` method represents a single declaration (single interface in this case). However, the assertion itself will be performed on every available interface. The last line in the `assertTrue` block will be evaluated as `true` or `false` providing the result for a given declaration.

{% hint style="info" %}
Each `KoDeclaration` comes with an API, comprising methods and properties, for verifying the declaration. Additionally, the Konsist API offers a `text` property for exceptional cases where the standard API falls short. This should be used as a last resort, and any issues encountered should be reported (see [Getting Help](/help/getting-help.md)).
{% endhint %}

### Assert False

The `assertFalse` is a negation of the `assertTrue` method. In the below snippet, the assertion (performed on the list of properties) verifies if none of the properties has the `Inject` annotation:

```kotlin
Konsist
    .scopeFromProject()
    .properties()
    .assertFalse { 
        it.hasAnnotationOf(Inject::class)
    }
```

This assertion verifies that no property has `public` (an explicit `public` modifier) or default (implicit `public` modifier) modifiers:

```kotlin
Konsist
    .scopeFromProject()
    .properties()
    .assertFalse { 
        it.hasPublicOrDefaultModifier
    }
```

### Assert Empty

This assertion helps to verify if the given list of declarations is empty.

```kotlin
Konsist
    .scopeFromProject()
    .classes()
    .assertEmpty()
```

### Assert Not Empty

This assertion helps to verify if the given list of declarations is not empty.

```kotlin
Konsist
    .scopeFromProject()
    .classes()
    .assertNotEmpty()
```

## Assertion Parameters

### Test Name

Assertions offer a set of parameters allowing you to tweak the assertion behavior. By default, the test name is derived from the JUnit test method name (for JUnit 5 dynamic tests, the name of the `@TestFactory` method). For Kotest the test name can't be determined, so it is omitted from the error message. Register `KoJUnitExtension` (JUnit 5 dynamic tests) or `KoKotestExtension` (Kotest 6) to use the name of the running test (see [Explicit Test Names](/advanced/dynamic-konsist-tests/explicit-test-names.md)), or set the `testName` argument to use a custom test name (displayed in the error message and used for suppression, see [Suppress Konsist Test](/writing-tests/suppressing-konsist-test.md)).

### Strict

You can also enable strict verification (the assertion fails if the declaration list is empty or contains only `null` values) by setting the `strict` argument to `true`:

```kotlin
Konsist
    .scopeFromProject() 
    .classes()
    .assertFalse(strict = true) { ... }
```

### Additional Message

The `additionalMessage` param allows providing an additional message that will be displayed with the failing test. This may be a more detailed description of the problem or a hint on how to fix the issue.

```kotlin
Konsist
    .scopeFromProject() 
    .classes()
    .assertFalse(additionalMessage = "Do X to fix the issue") { ... }
```

### Rule

The `rule` param accepts a `KoRule` describing what the assertion checks, why the rule exists and how to fix a violation. The rule is displayed in the failure message, so a developer (or an AI agent) knows how to fix the issue:

```kotlin
Konsist
    .scopeFromProject()
    .classes()
    .withNameEndingWith("ViewModel")
    .assertTrue(
        rule = KoRule(
            id = "VM-001",
            title = "ViewModels must extend BaseViewModel.",
            reason = "Lifecycle handling lives in BaseViewModel.",
            description = "Applies to every class with the ViewModel suffix.",
            howToFix = "Change the parent class to BaseViewModel.",
            goodExample = "class LoginViewModel : BaseViewModel()",
            badExample = "class LoginViewModel : ViewModel()",
        ),
    ) { it.hasParentClassWithName("BaseViewModel") }
```

```
Assert 'view models extend BaseViewModel' was violated (1 time).
ID: VM-001
RULE: ViewModels must extend BaseViewModel.
DESCRIPTION: Applies to every class with the ViewModel suffix.
REASON: Lifecycle handling lives in BaseViewModel.
HOW TO FIX: Change the parent class to BaseViewModel.
GOOD EXAMPLE:
class LoginViewModel : BaseViewModel()
BAD EXAMPLE:
class LoginViewModel : ViewModel()
Invalid declarations:
└── Class LoginViewModel file:///project/app/src/main/kotlin/com/myapp/LoginViewModel.kt:3:1
```

| Field         | Required | Label in message | Description                                                                                  |
| ------------- | -------- | ---------------- | -------------------------------------------------------------------------------------------- |
| `id`          | Yes      | `ID:`            | Unique rule identifier (e.g. `VM-001`), so a developer or an AI agent can refer to the rule. |
| `title`       | Yes      | `RULE:`          | One sentence that says what the rule checks.                                                 |
| `description` | No       | `DESCRIPTION:`   | Additional details about the rule, e.g. its scope or exceptions.                             |
| `reason`      | Yes      | `REASON:`        | Why the rule exists.                                                                         |
| `howToFix`    | No       | `HOW TO FIX:`    | How to fix a violation.                                                                      |
| `goodExample` | No       | `GOOD EXAMPLE:`  | A short code sample that follows the rule.                                                   |
| `badExample`  | No       | `BAD EXAMPLE:`   | A short code sample that violates the rule.                                                  |

* Fields are displayed in the order listed above.
* Required fields must not be blank (otherwise `IllegalArgumentException` is thrown). Blank optional fields are not displayed.
* Common indentation is removed from `goodExample` and `badExample`, so a raw string (`"""..."""`) can be used.
* When both `rule` and `additionalMessage` are set, the rule is displayed first.

The `rule` param is available for every assertion (`assertTrue`, `assertFalse`, `assertEmpty`, `assertNotEmpty`, `assertNull`, `assertNotNull`) and for `assertArchitecture` (see [Architecture Assertion](/writing-tests/architecture-assert.md)).

## Add Failure Reason

Use `addFailureReason` inside the `assertTrue` / `assertFalse` block to explain why a given declaration violates the assertion. Reasons are displayed under the failing declaration. Reasons added for declarations that pass the assertion are ignored:

```kotlin
Konsist
    .scopeFromProject()
    .classes()
    .withNameEndingWith("UseCase")
    .assertTrue {
        val publicFunctions = it.functions().filter { function -> function.hasPublicOrDefaultModifier }

        if (publicFunctions.size != 1) {
            addFailureReason("Has ${publicFunctions.size} public functions: ${publicFunctions.joinToString { function -> function.name }}")
        }

        publicFunctions.size == 1
    }
```

```
Assert 'use case has single public function' was violated (1 time). Invalid declarations:
└── Class GetUserUseCase file:///project/app/src/main/kotlin/com/myapp/usecase/GetUserUseCase.kt:5:1
    └── Has 2 public functions: invoke, validate
```

{% hint style="info" %}
`additionalMessage` is displayed once for the whole assertion, while `addFailureReason` is displayed for each failing declaration. `addFailureReason` can be called multiple times for a single declaration.
{% endhint %}

{% hint style="info" %}
Gradle does not display the assertion message (including `additionalMessage`, `rule` and failure reasons) in the command line output by default. See [Enable Full Command Line Logging](/advanced/enable-full-command-line-logging.md).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.konsist.lemonappdev.com/writing-tests/declaration-assert.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
