{"id":19472358,"url":"https://github.com/aboutbits/spring-boot-testing","last_synced_at":"2026-01-27T11:12:19.109Z","repository":{"id":252377242,"uuid":"836775699","full_name":"aboutbits/spring-boot-testing","owner":"aboutbits","description":"Spring Boot - Testing","archived":false,"fork":false,"pushed_at":"2026-01-13T07:43:58.000Z","size":269,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-17T05:57:54.526Z","etag":null,"topics":["java","spring-boot","testing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aboutbits.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-01T14:29:31.000Z","updated_at":"2026-01-13T07:44:01.000Z","dependencies_parsed_at":"2025-01-22T10:23:36.846Z","dependency_job_id":"3e2c6e17-d8b6-4b41-bd4d-40a2647d878a","html_url":"https://github.com/aboutbits/spring-boot-testing","commit_stats":null,"previous_names":["aboutbits/spring-boot-testing"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/aboutbits/spring-boot-testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Fspring-boot-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Fspring-boot-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Fspring-boot-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Fspring-boot-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aboutbits","download_url":"https://codeload.github.com/aboutbits/spring-boot-testing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboutbits%2Fspring-boot-testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28812371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T07:41:26.337Z","status":"ssl_error","status_checked_at":"2026-01-27T07:41:08.776Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","spring-boot","testing"],"created_at":"2024-11-10T19:14:12.446Z","updated_at":"2026-01-27T11:12:19.093Z","avatar_url":"https://github.com/aboutbits.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Boot Testing\n\nTesting library for Spring Boot projects.\n\n## Setup\n\nAdd this library to the classpath by adding the following maven dependency. Versions can be found [here](../../packages)\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eit.aboutbits\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-testing\u003c/artifactId\u003e\n    \u003cversion\u003ex.x.x\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n\n### Validation\n\nThe validation tester allows us to quickly test simple validation constraints. Most commonly we use bean validation for this.\n\n#### Configuration\n\nTo use the validation tester in your project you need to extend both the [BaseValidationAssert.java](src/main/java/it/aboutbits/springboot/testing/validation/core/BaseValidationAssert.java) and the [BaseRuleBuilder.java](src/main/java/it/aboutbits/springboot/testing/validation/core/BaseRuleBuilder.java).\n\n```java\npublic class ValidationAssert extends BaseValidationAssert\u003cBaseRuleBuilder\u003c?\u003e\u003e {\n    protected ValidationAssert() {\n        super(new RuleBuilder());\n    }\n\n    public static ValidationAssert assertThatValidation() {\n        return new ValidationAssert();\n    }\n\n    public static final class RuleBuilder extends BaseRuleBuilder\u003cRuleBuilder\u003e {\n\n    }\n}\n```\n\nBy default, the validation tester will assume that all properties of type `Record` are substructures. Therefore, using the `@Valid` annotation is required to make sure that validation for those records is triggered.\nYou can add a class to a whitelist to disable this behavior:\n\n```java\n\npublic class ValidationConfig {\n    public static void configure() {\n        ValidationAssert.registerNonBeanType(NotValidated.class);\n    }\n}\n\npublic class ValidationAssert extends BaseValidationAssert\u003cBaseRuleBuilder\u003c?\u003e\u003e {\n    static {\n        ValidationConfig.configure();\n    }\n\n    // ...\n}\n```\n\n#### Usage\n\nEach property is required to have at least one rule defined. You can add multiple rules for the same property as needed to combine more complex rulesets.\nThe tester will fail if not all properties have rules. In case you have properties without any restrictions, use the `notValidated` rule.\n\nThe validation tester works by taking in a **valid** parameter. It will then mutate the parameter internally and test each property with an invalid value. Then a check is done if a validation violation is raised as expected.\n\nIn any case, the call to `isCompliant` is required at the end and then triggers the actual assertion.\n\nYou can use plain bean validation to verify a Record:\n\n```java\nimport jakarta.validation.constraints.Future;\nimport jakarta.validation.constraints.NotNull;\nimport jakarta.validation.constraints.Past;\nimport org.springframework.lang.Nullable;\n\npublic record SomeParameter(\n        @NotBlank\n        String name,\n        @Min(18)\n        int age,\n        @NotNull\n        @Past\n        LocalDate birthDay,\n        @Nullable\n        String something,\n        String notValidatedAtAll\n) {\n}\n\n\n@Test\nvoid testValidation() {\n    var validParameter = new SomeParameter(\"Sepp\", 32);\n\n    assertThatValidation().of(validParameter)\n            .usingBeanValidation()\n            .notBlank(\"name\")\n            .min(\"age\", 18)\n            .notNull(\"birthDay\")\n            .past(\"birthDay\")\n            .nullable(\"something\")\n            .notValidated(\"notValidatedAtAll\")\n            .isCompliant();\n}\n```\n\nAlternatively you can use a method call to a service function to verify the validation. This is the preferred way as it makes sure that the bean validation is both triggered and also valid.\n\n```java\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic record SomeParameter(\n        @NotBlank\n        String name,\n        @Min(18)\n        int age\n) {\n}\n\n@Autowired\nprivate MyService myService;\n\n\n@Test\nvoid testValidation() {\n    var validParameter = new SomeParameter(\"Sepp\", 32);\n\n    assertThatValidation().of(validParameter)\n            .calling(myService::create)\n            .notBlank(\"name\")\n            .min(\"age\", 18)\n            .isCompliant();\n}\n\n@Test\nvoid testValidationWithIdParameter() {\n    var validParameter = new SomeParameter(\"Sepp\", 32);\n\n    assertThatValidation().of(validParameter)\n            .calling(myService::update, new User.ID(3L))\n            .notBlank(\"name\")\n            .min(\"age\", 18)\n            .isCompliant();\n}\n```\n\n#### Adding Custom Validation Rules\n\nYou can add new rules by creating a new interface:\n\n```java\npublic interface MyShinyNewRule\u003cV extends BaseRuleBuilder\u003c?\u003e\u003e extends ValidationRulesData {\n    default V shiny(@NonNull String property) {\n        this.addRule(new Rule(property, InertValueSource.class, new Object[0]));\n        return (BaseRuleBuilder) this;\n    }\n}\n```\n\nTo use the newly created rule, we can simply have our `RuleBuilder` implement the interface:\n\n```java\npublic class ValidationAssert extends BaseValidationAssert\u003cBaseRuleBuilder\u003c?\u003e\u003e {\n    // ...\n\n    public static final class RuleBuilder extends BaseRuleBuilder\u003cRuleBuilder\u003e implements MyShinyNewRule\u003cRuleBuilder\u003e {\n\n    }\n}\n```\n\nThe `Rule` requires the property name, a value-source and an array of optional parameters. For example `min(property, minValue)` takes in the additional parameter for the value.\nNote that the value-source must return **invalid** values. This is required because the tool is actively trying to violate the rules to check if an error is raised.\n\n#### Adding Custom Value Sources\n\nYou can add custom values sources by implementing the `ValueSource` interface.\nWhile the interface can not enforce the static function `registerType`, it is best practice to implement it in a way that keeps this extensible.\nThis way we can use the same logical value-source for multiple property types.\n\nHere is an example:\n\n```java\npublic class EmptyValueSource implements ValueSource {\n    private static final Map\u003cClass\u003c?\u003e, Function\u003cObject[], Stream\u003c?\u003e\u003e\u003e TYPE_SOURCES = new HashMap\u003c\u003e();\n\n    static {\n        TYPE_SOURCES.put(\n                String.class,\n                (Object[] args) -\u003e Stream.of(\"\")\n        );\n        TYPE_SOURCES.put(\n                Set.class,\n                (Object[] args) -\u003e Stream.of(new HashSet\u003c\u003e())\n        );\n        TYPE_SOURCES.put(\n                List.class,\n                (Object[] args) -\u003e Stream.of(new ArrayList\u003c\u003e())\n        );\n    }\n\n    public static void registerType(Class\u003c?\u003e type, Function\u003cObject[], Stream\u003c?\u003e\u003e source) {\n        TYPE_SOURCES.put(type, source);\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public \u003cT\u003e Stream\u003cT\u003e values(Class\u003cT\u003e propertyClass, Object... args) {\n        var sourceFunction = TYPE_SOURCES.get(propertyClass);\n        if (sourceFunction != null) {\n            return (Stream\u003cT\u003e) sourceFunction.apply(args);\n        }\n\n        throw new IllegalArgumentException(\"Property class not supported!\");\n    }\n}\n```\n\n#### Adding Support for Custom Types\n\n_Note: CustomType wrappers from the `toolbox` are currently not natively supported._\n\nAdding custom types will require some extension to the existing value-sources. Those need to become aware of the new type in order to produce values of said type.\n\nThis can be done by extending the configuration:\n\n```java\npublic record SurnameType(\n        String value\n) {\n}\n\npublic class ValidationConfig {\n    public static void configure() {\n        EmptyValueSource.registerType(\n                SurnameType.class,\n                (args) -\u003e {\n                    return Stream.of(new SurnameType(\"\"));\n                }\n        );\n\n        // ...\n    }\n}\n\npublic class ValidationAssert extends BaseValidationAssert\u003cBaseRuleBuilder\u003c?\u003e\u003e {\n    static {\n        ValidationConfig.configure();\n    }\n\n    // ...\n}\n```\n\n## Local Development\n\nTo use this library as a local development dependency, you can simply refer to the version `BUILD-SNAPSHOT`.\n\nCheck out this repository and run the maven goal `install`. This will build and install this library as version `BUILD-SNAPSHOT` into your local maven cache.\n\nNote that you may have to tell your IDE to reload your main maven project each time you build the library.\n\n## Build \u0026 Publish\n\nTo build and publish the chart, visit the GitHub Actions page of the repository and trigger the workflow \"Release Package\" manually.\n\n## Information\n\nAbout Bits is a company based in South Tyrol, Italy. You can find more information about us on [our website](https://aboutbits.it).\n\n### Support\n\nFor support, please contact [info@aboutbits.it](mailto:info@aboutbits.it).\n\n### Credits\n\n- [All Contributors](../../contributors)\n\n### License\n\nThe MIT License (MIT). Please see the [license file](license.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutbits%2Fspring-boot-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faboutbits%2Fspring-boot-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboutbits%2Fspring-boot-testing/lists"}