{"id":29189024,"url":"https://github.com/autoparams/autoparams","last_synced_at":"2026-04-05T15:00:56.822Z","repository":{"id":42507198,"uuid":"345092262","full_name":"AutoParams/AutoParams","owner":"AutoParams","description":"AutoParams is a versatile test data generator designed for parameterized tests in Java and Kotlin.","archived":false,"fork":false,"pushed_at":"2026-03-31T06:01:59.000Z","size":1683,"stargazers_count":368,"open_issues_count":24,"forks_count":60,"subscribers_count":20,"default_branch":"main","last_synced_at":"2026-03-31T06:05:25.278Z","etag":null,"topics":["java","junit5","kotlin","spring","tdd","unit","unit-testing"],"latest_commit_sha":null,"homepage":"https://autoparams.github.io/","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/AutoParams.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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":"2021-03-06T12:48:00.000Z","updated_at":"2026-03-31T05:48:23.000Z","dependencies_parsed_at":"2022-08-12T10:01:13.084Z","dependency_job_id":"31f34c64-a302-4e19-b495-eb6bc6dc0277","html_url":"https://github.com/AutoParams/AutoParams","commit_stats":null,"previous_names":["javaunit/autoparams"],"tags_count":105,"template":false,"template_full_name":null,"purl":"pkg:github/AutoParams/AutoParams","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutoParams%2FAutoParams","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutoParams%2FAutoParams/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutoParams%2FAutoParams/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutoParams%2FAutoParams/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AutoParams","download_url":"https://codeload.github.com/AutoParams/AutoParams/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutoParams%2FAutoParams/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31439442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T13:13:19.330Z","status":"ssl_error","status_checked_at":"2026-04-05T13:13:17.778Z","response_time":75,"last_error":"SSL_read: 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","junit5","kotlin","spring","tdd","unit","unit-testing"],"created_at":"2025-07-01T23:01:26.522Z","updated_at":"2026-04-05T15:00:56.809Z","avatar_url":"https://github.com/AutoParams.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AutoParams\n\n[![CI](https://github.com/AutoParams/AutoParams/actions/workflows/ci.yml/badge.svg)](https://github.com/AutoParams/AutoParams/actions/workflows/ci.yml)\n[![Publish](https://github.com/AutoParams/AutoParams/actions/workflows/publish.yml/badge.svg)](https://github.com/AutoParams/AutoParams/actions/workflows/publish.yml)\n\n**AutoParams** is a JUnit 5 extension for automatic test data generation, inspired by AutoFixture.\n\nManually creating test data is often repetitive and distracts from the core logic of the test. AutoParams eliminates this boilerplate by supplying automatically generated values to your test method parameters, allowing you to write concise and focused tests.\n\nGetting started is simple: annotate your `@Test` method with `@AutoParams`, and the parameters will be populated with generated data.\n\n```java\n@Test\n@AutoParams\nvoid testMethod(int a, int b) {\n    Calculator sut = new Calculator();\n    int actual = sut.add(a, b);\n    assertEquals(a + b, actual);\n}\n```\n\nIn the example above, `a` and `b` are automatically generated, making the test cleaner and reducing the need for manual setup or value triangulation.\n\nAutoParams also supports more advanced scenarios. When multiple generated values need to share a reference—such as reviews referring to the same product—you can use the `@Freeze` annotation to ensure consistency.\n\n```java\n@AllArgsConstructor\n@Getter\npublic class Product {\n\n    private final UUID id;\n    private final String name;\n    private final BigDecimal priceAmount;\n}\n```\n\n```java\n@AllArgsConstructor\n@Getter\npublic class Review {\n\n    private final UUID id;\n    private final UUID reviewerId;\n    private final Product product;\n    private final int rating;\n    private final String comment;\n}\n```\n\n```java\n@Test\n@AutoParams\nvoid testMethod(@Freeze Product product, Review[] reviews) {\n    for (Review review : reviews) {\n        assertSame(product, review.getProduct());\n    }\n}\n```\n\nThis ensures that all generated `Review` instances refer to the same frozen `Product`, simplifying test setup in scenarios involving shared dependencies.\n\n## Requirements\n\n- JDK 1.8 or higher\n\n## Install\n\n### Maven\n\nFor Maven, you can add the following dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.autoparams\u003c/groupId\u003e\n  \u003cartifactId\u003eautoparams\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\nFor Gradle, use:\n\n```groovy\ntestImplementation 'io.github.autoparams:autoparams:11.3.2'\n```\n\n## Features\n\nAutoParams provides a set of features designed to make your tests more expressive and reduce repetitive setup. Here are some of its key capabilities:\n\n### `@FreezeBy` Annotation\n\nThe `@FreezeBy` annotation enables fine-grained control over value freezing in tests. It allows you to freeze a single value and reuse it across multiple generation targets that match specific conditions, such as type or name. This helps improve test readability and ensures consistency among generated values.\n\n#### Matching Strategies\n\nAutoParams provides several matching strategies that determine which targets should receive the frozen value during object generation. The following examples illustrate some strategies:\n\n- `EXACT_TYPE`\n\n  Reuses the frozen value for all targets with the exact same type.\n\n  ```java\n  @AllArgsConstructor\n  @Getter\n  public class StringContainer {\n\n      private final String value;\n  }\n  ```\n\n  ```java\n  import static autoparams.customization.Matching.EXACT_TYPE;\n\n  public class TestClass {\n\n      @Test\n      @AutoParams\n      void testMethod(\n          @FreezeBy(EXACT_TYPE) String s1,\n          String s2,\n          StringContainer container\n      ) {\n          assertSame(s1, s2);\n          assertSame(s1, container.getValue());\n      }\n  }\n  ```\n\n  In this example, all `String` targets—including the `String` field inside `StringContainer`—are generated with the same frozen value.\n\n- `IMPLEMENTED_INTERFACES`\n\n  Reuses the frozen value for targets whose types are interfaces that the frozen value's type implements.\n\n  ```java\n  import static autoparams.customization.Matching.IMPLEMENTED_INTERFACES;\n\n  public class TestClass {\n\n      @Test\n      @AutoParams\n      void testMethod(\n          @FreezeBy(IMPLEMENTED_INTERFACES) String s1,\n          CharSequence chars,\n          StringContainer container\n      ) {\n          assertSame(s1, chars);\n          assertNotSame(s1, container.getValue());\n      }\n  }\n  ```\n\n  In this example, `String` implements `CharSequence`, so the same value is reused for both `s1` and `chars`. `StringContainer` is not affected because its type is not an interface.\n\n- `PARAMETER_NAME`\n\n  Reuses the frozen value for other targets with matching names.\n\n  ```java\n  import static autoparams.customization.Matching.PARAMETER_NAME;\n\n  public class TestClass {\n\n      @Test\n      @AutoParams\n      void testMethod(\n          @FreezeBy(PARAMETER_NAME) UUID reviewerId,\n          Review review\n      ) {\n          assertNotSame(reviewerId, review.getId());\n          assertSame(reviewerId, review.getReviewerId());\n      }\n  }\n  ```\n\n  This strategy is useful when names follow a consistent convention that reflects their role.\n\nYou can also combine multiple matching strategies to broaden the scope of freezing.\n\n```java\nimport static autoparams.customization.Matching.EXACT_TYPE;\nimport static autoparams.customization.Matching.IMPLEMENTED_INTERFACES;\n\npublic class TestClass {\n\n    @Test\n    @AutoParams\n    void testMethod(\n        @FreezeBy({ EXACT_TYPE, IMPLEMENTED_INTERFACES }) String s1,\n        String s2,\n        CharSequence chars\n    ) {\n        assertSame(s1, s2);\n        assertSame(s1, chars);\n    }\n}\n```\n\nIn this example, the frozen value `s1` is reused for both `s2` (same type) and `chars` (interface implemented by `String`).\n\n#### Shorthand for `EXACT_TYPE`\n\nUsing `@Freeze` is equivalent to `@FreezeBy(EXACT_TYPE)`. It's a convenient shorthand for the most common matching strategy.\n\n```java\n@Test\n@AutoParams\nvoid testMethod(@Freeze String s1, String s2) {\n    assertSame(s1, s2);\n}\n```\n\n### Setting the Range of Values\n\nYou can constrain the range of automatically generated values using the `@Min` and `@Max` annotations. These let you define minimum and maximum bounds for numeric parameters, ensuring that generated values fall within a specified range.\n\nTo apply a range, annotate the parameter with `@Min` and/or `@Max` as needed.\n\nHere's an example:\n\n```java\n@Test\n@AutoParams\nvoid testMethod(@Min(1) @Max(10) int value) {\n    assertTrue(value \u003e= 1);\n    assertTrue(value \u003c= 10);\n}\n```\n\nIn this test, the `value` parameter will always be an integer between `1` and `10`, inclusive.\n\nThe `@Min` and `@Max` annotations are compatible with the following types:\n\n- `byte`\n- `java.lang.Byte`\n- `short`\n- `java.lang.Short`\n- `int`\n- `java.lang.Integer`\n- `long`\n- `java.lang.Long`\n- `float`\n- `java.lang.Float`\n- `double`\n- `java.lang.Double`\n\nBy combining `@Min` and `@Max` with `@AutoParams`, you can strike a balance between randomness and control, making your parameterized tests more robust and predictable.\n\n### `ResolutionContext` class\n\nThe `ResolutionContext` class provides the core mechanism for generating test data. While it is used internally by AutoParams, you can also instantiate and use it directly in your own test code when needed.\n\nHere's an example:\n\n```java\n@Test\nvoid testMethod() {\n    ResolutionContext context = new ResolutionContext();\n    Product product = context.resolve();\n    Review review = context.resolve();\n}\n```\n\nIn this example, `ResolutionContext` is used to manually generate instances of `Product` and `Review` outside of the `@AutoParams` annotation. This offers more control and flexibility for writing custom test logic or handling special cases.\n\n### `Factory\u003cT\u003e` class\n\nThe `Factory\u003cT\u003e` class is useful when you need to generate multiple instances of the same type. It allows you to create single instances or collections of generated objects on demand.\n\nHere's an example:\n\n```java\n@Test\nvoid testMethod() {\n    Factory\u003cProduct\u003e factory = Factory.create(Product.class);\n    Product product = factory.get();\n    List\u003cProduct\u003e products = factory.getRange(10);\n}\n```\n\nIn this example, a `Factory\u003cProduct\u003e` is created to produce `Product` instances. The `get()` method creates a single instance, while `getRange(n)` returns a list of `n` instances. This approach is particularly helpful when you need bulk data generation in your tests.\n\n### Collections and Arrays\n\nAutoParams can generate collections and arrays automatically. By default, the size of generated collections and arrays is 3, but you can override this using annotations such as `@Size`.\n\nFor example, the following tests verify that AutoParams generates an `ArrayList\u003cString\u003e` and a `String[]` with exactly 5 elements when the `@Size(min = 5)` constraint is applied:\n\n```java\n@Test\n@AutoParams\nvoid testMethod(@Size(min = 5) ArrayList\u003cString\u003e arrayList) {\n    assertThat(arrayList).hasSize(5);\n}\n```\n\n```java\n@Test\n@AutoParams\nvoid testMethod(@Size(min = 5) String[] array) {\n    assertThat(array).hasSize(5);\n}\n```\n\nThis allows you to work with realistic data sizes while keeping your test code clean and concise.\n\n### Customization\n\nCustomization is one of the most powerful features offered by AutoParams. It gives you full control over how test data is generated, allowing you to enforce business rules or tailor the data to meet specific testing needs.\n\nFor example, suppose the `Product` entity must follow these business rules:\n\n- `priceAmount` must be greater than or equal to `10`\n- `priceAmount` must be less than or equal to `10000`\n\nYou can implement these rules using a custom generator by extending `ObjectGeneratorBase\u003cT\u003e`:\n\n```java\npublic class ProductGenerator extends ObjectGeneratorBase\u003cProduct\u003e {\n\n    @Override\n    protected Product generateObject(ObjectQuery query, ResolutionContext context) {\n        UUID id = context.resolve();\n        String name = context.resolve();\n\n        ThreadLocalRandom random = ThreadLocalRandom.current();\n        BigDecimal priceAmount = new BigDecimal(random.nextInt(10, 10000 + 1));\n\n        return new Product(id, name, priceAmount);\n    }\n}\n```\n\nThis custom generator creates a `Product` instance that adheres to the business constraints. It uses `ResolutionContext` to generate supporting values like `id` and `name`, and applies explicit logic to generate a valid `priceAmount`.\n\nYou can apply this custom generator using the `@Customization` annotation:\n\n```java\n@Test\n@AutoParams\n@Customization(ProductGenerator.class)\nvoid testMethod(Product product) {\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10)) \u003e= 0);\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10000)) \u003c= 0);\n}\n```\n\nIn this test, AutoParams uses `ProductGenerator` to ensure that the `Product` instance respects the required pricing constraints.\n\nYou can also apply multiple custom generators at once by listing them in the `@Customization` annotation:\n\n```java\npublic class ReviewGenerator extends ObjectGeneratorBase\u003cReview\u003e {\n\n    @Override\n    protected Review generateObject(ObjectQuery query, ResolutionContext context) {\n        UUID id = context.resolve();\n        UUID reviewerId = context.resolve();\n        Product product = context.resolve();\n        String comment = context.resolve();\n\n        ThreadLocalRandom random = ThreadLocalRandom.current();\n        int rating = random.nextInt(1, 5 + 1);\n\n        return new Review(id, reviewerId, product, rating, comment);\n    }\n}\n```\n\n```java\n@Test\n@AutoParams\n@Customization({ ProductGenerator.class, ReviewGenerator.class })\nvoid testMethod(Product product, Review review) {\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10)) \u003e= 0);\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10000)) \u003c= 0);\n    assertTrue(review.getRating() \u003e= 1);\n    assertTrue(review.getRating() \u003c= 5);\n}\n```\n\nAlternatively, if you prefer to encapsulate multiple generators into a single reusable configuration, you can extend `CompositeCustomizer`:\n\n```java\npublic class DomainCustomizer extends CompositeCustomizer {\n\n    public DomainCustomizer() {\n        super(\n            new ProductGenerator(),\n            new ReviewGenerator()\n        );\n    }\n}\n```\n\n```java\n@Test\n@AutoParams\n@Customization(DomainCustomizer.class)\nvoid testMethod(Product product, Review review) {\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10)) \u003e= 0);\n    assertTrue(product.getPriceAmount().compareTo(BigDecimal.valueOf(10000)) \u003c= 0);\n    assertTrue(review.getRating() \u003e= 1);\n    assertTrue(review.getRating() \u003c= 5);\n}\n```\n\nThis approach gives you a clean and reusable way to manage related custom generators, improving maintainability and consistency across your test suite.\n\n#### Customization Scoping\n\nThe `@Customization` annotation can also be applied to individual parameters within a test method. When used in this way, the specified customization will apply to that parameter and all subsequent parameters of the same type—unless explicitly overridden.\n\nThis allows for fine-grained control over how test data is generated, making it easier to set up complex, context-specific scenarios.\n\nHere's an example of a custom generator that creates a free product (with zero prices):\n\n```java\npublic class FreeProductGenerator extends ObjectGeneratorBase\u003cProduct\u003e {\n\n    @Override\n    protected Product generateObject(ObjectQuery query, ResolutionContext context) {\n        UUID id = context.resolve();\n        String name = context.resolve();\n\n        BigDecimal priceAmount = BigDecimal.ZERO;\n\n        return new Product(id, name, priceAmount);\n    }\n}\n```\n\nAnd here’s how to apply it to a specific parameter:\n\n```java\n@Test\n@AutoParams\n@Customization(DomainCustomizer.class)\nvoid testMethod(\n    Product product1,\n    @Customization(FreeProductGenerator.class) Product product2\n) {\n    assertTrue(product1.getPriceAmount().compareTo(BigDecimal.valueOf(10)) \u003e= 0);\n    assertTrue(product1.getPriceAmount().compareTo(BigDecimal.valueOf(10000)) \u003c= 0);\n\n    assertEquals(BigDecimal.ZERO, product2.getPriceAmount());\n}\n```\n\nIn this test, `product1` is generated using the default logic from `DomainCustomizer`, while `product2` uses the `FreeProductGenerator` to produce a free product. This demonstrates how per-parameter customization gives you precise control over test data generation.\n\n#### One-time Customizations with DSL(Domain-Specific Language)\n\nAutoParams allows you to define one-time customizations directly within your test method using a domain-specific language(DSL). This is useful when you want to customize test data generation in a highly localized, context-specific way—without having to create separate generator classes.\n\n```java\nimport static autoparams.customization.dsl.ArgumentCustomizationDsl.set;\n\npublic class TestClass {\n\n    @Test\n    @AutoParams\n    void testMethod(Product product, @Max(5) int rating, ResolutionContext context) {\n        context.customize(\n            set(Review::getProduct).to(product),\n            set(Review::getRating).to(rating)\n        );\n        Review review = context.resolve();\n        assertSame(product, review.getProduct());\n        assertEquals(rating, review.getRating());\n    }\n}\n```\n\nIn this example, we use the `set` static method from the `ArgumentCustomizationDsl` class to customize the behavior of the `ResolutionContext`. Specifically:\n\n- The `product` property in any `Review` instance created by the context will be set to the `product` parameter of the test.\n- Likewise, the `rating` property will be set to the `rating` parameter.\n\nThis approach is especially useful for quickly fixing values without defining a full custom generator or specifying customization at the test method level. It improves the readability and maintainability of localized scenarios by keeping custom logic close to the test logic.\n\nYou can also apply the same DSL customizations using `Factory\u003cT\u003e`.\n\n```java\nimport static autoparams.customization.dsl.ArgumentCustomizationDsl.set;\n\npublic class TestClass {\n\n    @Test\n    @AutoParams\n    void testMethod(Product product, @Max(5) int rating, Factory\u003cReview\u003e factory) {\n        Review review = factory.get(\n            set(Review::getProduct).to(product),\n            set(Review::getRating).to(rating)\n        );\n        assertSame(product, review.getProduct());\n        assertEquals(rating, review.getRating());\n    }\n}\n```\n\nThe `Factory\u003cT\u003e` class provides a convenient way to create customized objects when working with a single type. It avoids managing an explicit resolution context and keeps the test focused on the instances under test.\n\n\u003e **Note**  \n\u003e The `set` method relies on the availability of parameter names at runtime. However, Java does not include parameter names in bytecode by default. To ensure this works correctly, you can:\n\u003e\n\u003e 1. Use a record class, which preserves parameter names by design.\n\u003e 1. Compile with the `-parameters` option when using `javac`, or `-java-parameters` when using `kotlinc`.  \n\u003e    If you're using Spring Boot, this option is automatically enabled when you use the [Spring Boot Gradle plugin](https://docs.spring.io/spring-boot/gradle-plugin/reacting.html#reacting-to-other-plugins.java) or the [Spring Boot Maven plugin](https://docs.spring.io/spring-boot/maven-plugin/using.html).\n\u003e 1. Apply the `@ConstructorProperties` annotation to constructors to explicitly declare parameter names.  \n\u003e    This annotation works only for constructors and has no effect on regular methods. If you're using Lombok and the constructor is generated by a Lombok annotation such as `@AllArgsConstructor`, the `@ConstructorProperties` annotation can be automatically added by enabling the `lombok.anyConstructor.addConstructorProperties = true` option.  \n\u003e    For more details, see: https://projectlombok.org/features/constructor\n\n#### Settable Properties\n\nIf a class follows the JavaBeans convention—meaning it has a no-arguments constructor and public setter methods—AutoParams can automatically populate its properties using the `InstancePropertyWriter` customizer.\n\nHere's a simple example:\n\n```java\n@Getter\n@Setter\npublic class User {\n\n    private Long id;\n    private String name;\n}\n```\n\nBy applying the `InstancePropertyWriter` customizer, AutoParams will generate and assign values to the `id` and `name` properties automatically:\n\n```java\n@Test\n@AutoParams\n@Customization(InstancePropertyWriter.class)\nvoid testMethod(User user) {\n    assertNotNull(user.getId());\n    assertNotNull(user.getName());\n}\n```\n\nIn this test, the `User` object is created using its default constructor, and AutoParams sets values on its writable properties via their setters. This is especially useful when working with legacy models or data transfer objects(DTOs) that do not have constructors covering all fields.\n\n### Logging for Object Resolution\n\nAutoParams provides detailed logging capabilities that help you understand how objects are being resolved during test execution. To enable logging, apply the `@LogResolution` annotation to your test method alongside `@AutoParams`. When enabled, the resolution log is printed to standard output during test execution, making it easy to trace how each value is generated.\n\nFor example, resolving a `User` class produces a detailed trace. Given the following class:\n\n```java\n@AllArgsConstructor\n@Getter\n@ToString\npublic class User {\n\n    private final UUID id;\n    private final String email;\n    private final String username;\n}\n```\n\nRunning the following code:\n\n```java\n@Test\n@AutoParams\n@LogResolution\nvoid testMethod(User user) {\n}\n```\n\nWill print a hierarchical visualization of the resolution process:\n\n```text\nUser user (5ms)\n ├─ UUID id → fbdf7aa8-1af7-4308-bc64-ee9dbfeba8d2 (1ms)\n ├─ String email → 53bf56a3-8a42-47f3-a5c9-854862ea4a56@test.com (2ms)\n └─ String username → usernamec6962921-ab77-4dbc-a71d-6932a9faa5be (1ms)\n```\n\nThe log uses a tree structure to show the resolution hierarchy:\n- Each level shows the query type and parameter name\n- `→` indicates the generated value\n- Time taken for each resolution is shown in parentheses\n- Indentation levels represent the depth of the resolution chain\n\nThis logging is particularly valuable when working with:\n- Customizations\n- Complex object hierarchies\n- Dependency injection scenarios\n- Debugging test failures related to object generation\n\n### Parameterized Tests\n\nAutoParams also supports **parameterized tests**, allowing you to execute the same test logic with multiple sets of input data. With AutoParams, you can seamlessly combine manually specified values with automatically generated test data—enabling both flexibility and convenience.\n\nHere are some of the features you can use for parameterized tests.\n\n#### `@ValueAutoSource` Annotation\n\nThe `@ValueAutoSource` annotation is a simple yet powerful tool for writing parameterized tests with AutoParams.\n\n```java\n@ParameterizedTest\n@ValueAutoSource(strings = { \"Camera\", \"Candle\" })\nvoid testMethod(String name, Factory\u003cProduct\u003e factory) {\n    Product product = factory.get(\n        freezeArgument(\"name\").to(name)\n    );\n    assertTrue(product.getName().startsWith(\"Ca\"));\n}\n``` \n\n\u003e **Note**  \n\u003e This feature depends on parameter name availability. See the note in the [One-time Customizations with DSL](#one-time-customizations-with-dsldomain-specific-language) section for details.\n\nIn this example, the test method is executed twice—once with `\"Camera\"` and once with `\"Candle\"` as the value of the `name` parameter. The `factory` parameter is resolved automatically by AutoParams and can be customized using the DSL, as shown with `freezeArgument`.\n\nThis enables the creation of test objects (`Product` in this case) that are partially controlled (e.g., a fixed name) and partially randomized (e.g., all other properties), striking a balance between specificity and variety.\n\nThe usage of `@ValueAutoSource` is similar to JUnit 5's `@ValueSource`, and it supports the following types of literal values:\n\n- `short`\n- `byte`\n- `int`\n- `long`\n- `float`\n- `double`\n- `char`\n- `boolean`\n- `java.lang.String`\n- `java.lang.Class`\n\n#### `@CsvAutoSource` Annotation\n\nThe `@CsvAutoSource` annotation lets you define repeated test inputs in CSV format, similar to JUnit 5’s @CsvSource. Any parameters not explicitly provided in the CSV rows will be automatically generated by AutoParams.\n\n```java\n@ParameterizedTest\n@CsvAutoSource({\n    \"Product 1, 500\",\n    \"Product 2, 10000\"\n})\nvoid testMethod(String name, BigDecimal priceAmount, UUID id) {\n    Product product = new Product(id, name, priceAmount);\n    assertTrue(product.getName().startsWith(\"Product\"));\n}\n```\n\nIn this example, the `@CsvAutoSource` annotation provides values for the `name` and `priceAmount` parameters. The remaining parameter(`id`) is resolved automatically by AutoParams.\n\nThe test will run once for each line in the CSV input array—twice in this case—allowing you to repeat the same test logic with multiple fixed inputs while still benefiting from automatic value generation for the rest.\n\nThis approach makes it easy to test combinations of fixed and dynamic values in a concise and expressive way.\n\n#### `@MethodAutoSource` Annotation\n\nThe `@MethodAutoSource` annotation combines the features of JUnit 5’s `@MethodSource` and AutoParams’s `@AutoSource`. You can specify a method that provides test data, and AutoParams will fill in any remaining parameters automatically.\n\n```java\n@ParameterizedTest\n@MethodAutoSource(\"testDataSource\")\nvoid testMethod(String name, BigDecimal priceAmount, UUID id) {\n    Product product = new Product(id, name, priceAmount);\n    assertTrue(product.getName().startsWith(\"Product\"));\n}\n\nstatic Stream\u003cArguments\u003e testDataSource() {\n    return Stream.of(\n        arguments(\"Product 1\", new BigDecimal(500)),\n        arguments(\"Product 2\", new BigDecimal(10000))\n    );\n}\n```\n\nIn this example, the `testDataSource` method provides values for the `name` and `priceAmount` parameters. The remaining parameter(`id`) is automatically resolved by AutoParams and provided as an argument to the test method.\n\nThis setup allows you to blend manually specified values with automatically generated ones, giving you both precision and variability in your parameterized tests.\n\n#### `@Repeat` Annotation\n\nThe `@Repeat` annotation allows you to run a test multiple times, generating fresh random values for unspecified parameters on each run.\n\n```java\n@ParameterizedTest\n@ValueAutoSource(ints = { 1, 2, 3 })\n@Repeat(5)\nvoid testMethod(int a, int b) {\n    Calculator sut = new Calculator();\n    int actual = sut.add(a, b);\n    assertEquals(a + b, actual);\n}\n```\n\nIn this example, the test is executed 15 times in total—five times for each of the values `1`, `2`, and `3` assigned to the parameter `a`. For each run, the value of `b` is automatically generated by AutoParams.\n\nIf you want AutoParams to generate values for **all** parameters and still repeat the test multiple times, you can combine `@AutoSource` with `@Repeat`.\n\n```java\n@ParameterizedTest\n@AutoSource\n@Repeat(10)\nvoid testMethod(int a, int b) {\n    Calculator sut = new Calculator();\n    int actual = sut.add(a, b);\n    assertEquals(a + b, actual);\n}\n```\n\nThis combination is useful when you want to explore a wider range of inputs and increase test coverage with minimal setup.\n\n### Constructor Selection Policy\n\nWhen AutoParams generates instances of complex types that have multiple constructors, it follows a specific policy to determine which constructor to use:\n\n1. Constructors annotated with `@ConstructorProperties` are prioritized.\n1. If no such annotation is present, AutoParams chooses the constructor with the **fewest** parameters.\n\nHere's an example:\n\n```java\n@Getter\npublic class ComplexObject {\n\n    private final int value1;\n    private final String value2;\n    private final UUID value3;\n\n    @ConstructorProperties({ \"value1\", \"value2\", \"value3\" })\n    public ComplexObject(int value1, String value2, UUID value3) {\n        this.value1 = value1;\n        this.value2 = value2;\n        this.value3 = value3;\n    }\n\n    @ConstructorProperties({ \"value1\", \"value2\" })\n    public ComplexObject(int value1, String value2) {\n        this(value1, value2, null);\n    }\n\n    public ComplexObject(int value1) {\n        this(value1, null, null);\n    }\n}\n```\n\n```java\n@Test\n@AutoParams\nvoid testMethod(ComplexObject object) {\n    assertNotNull(object.getValue2());\n    assertNull(object.getValue3());\n}\n```\n\nIn this example, AutoParams selects the constructor with the `@ConstructorProperties` annotation that has the fewest parameters—(`int`, `String`)—and assigns null to the `value3` field. This shows how constructor selection can affect the structure of the generated object.\n\n## `autoparams-spring`\n\nWhen testing a Spring application, you often need both of the following:\n\n- Beans provided by the **Spring IoC container**\n- Arbitrary test data automatically generated by **AutoParams**\n\nThe `autoparams-spring` extension bridges these two needs, allowing you to write test methods that receive **Spring-managed beans** and **AutoParams-generated arguments** side by side.\n\nThis means you can write tests that automatically inject service components from your application context and use auto-generated test data at the same time, with minimal setup.\n\n### Install\n\n#### Maven\n\nFor Maven, you can add the following dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.autoparams\u003c/groupId\u003e\n  \u003cartifactId\u003eautoparams-spring\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle\n\nFor Gradle, use:\n\n```groovy\ntestImplementation 'io.github.autoparams:autoparams-spring:11.3.2'\n```\n\n### `@UseBeans` Annotation\n\nSuppose your Spring application has a `HelloSupplier` bean that implements the `MessageSupplier` interface:\n\n```java\npublic interface MessageSupplier {\n\n    String getMessage(String name);\n}\n```\n\n```java\n@Component\npublic class HelloSupplier implements MessageSupplier {\n\n    @Override\n    public String getMessage(String name) {\n        return \"Hello, \" + name + \"!\";\n    }\n}\n```\n\nIf you want to test how your `MessageSupplier` bean behaves, you can use the `@UseBeans` annotation like this:\n\n```java\n@SpringBootTest\npublic class TestClass {\n\n    @Test\n    @AutoParams\n    @UseBeans\n    void testMethod(MessageSupplier service, String name) {\n        String message = service.getMessage(name);\n        assertTrue(message.startsWith(\"Hello\"));\n        assertTrue(message.contains(name));\n    }\n}\n```\n\nIn this test:\n\n- The `service` parameter is automatically resolved as a Spring bean.\n- The `name` parameter is randomly generated by AutoParams.\n\nThis allows you to seamlessly combine real Spring components with generated test data, making your tests both concise and expressive.\n\n## `autoparams-mockito`\n\n`autoparams-mockito` is an extension of AutoParams that enables the automatic creation of test doubles for interfaces and abstract classes using Mockito, a widely used mocking framework for Java. With this extension, AutoParams can generate test doubles seamlessly—with minimal setup.\n\n### Install\n\n#### Maven\n\nFor Maven, you can add the following dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.autoparams\u003c/groupId\u003e\n  \u003cartifactId\u003eautoparams-mockito\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle\n\nFor Gradle, use:\n\n```groovy\ntestImplementation 'io.github.autoparams:autoparams-mockito:11.3.2'\n```\n\n### Generating Test Doubles with Mockito\n\nSuppose you have an interface that represents a dependency:\n\n```java\npublic interface Dependency {\n\n    String getName();\n}\n```\n\nAnd a system under test that relies on this dependency:\n\n```java\npublic class SystemUnderTest {\n\n    private final Dependency dependency;\n\n    public SystemUnderTest(Dependency dependency) {\n        this.dependency = dependency;\n    }\n\n    public String getMessage() {\n        return \"Hello \" + dependency.getName();\n    }\n}\n```\n\nBy using the `@Customization(MockitoCustomizer.class)` annotation, AutoParams will automatically generate Mockito-based test doubles for eligible parameters (such as interfaces and abstract classes).\n\nHere’s an example:\n\n```java\n@Test\n@AutoParams\n@Customization(MockitoCustomizer.class)\nvoid testMethod(@Freeze Dependency stub, SystemUnderTest sut) {\n    when(stub.getName()).thenReturn(\"World\");\n    assertEquals(\"Hello World\", sut.getMessage());\n}\n```\n\nIn this test:\n\n- `stub` is a test double automatically generated by Mockito.\n- The `@Freeze` annotation ensures that the same `stub` instance is injected into the `SystemUnderTest`.\n- You can configure the test double using standard Mockito syntax.\n\nThis integration streamlines test setup, enabling you to focus on verifying behavior rather than wiring dependencies manually.\n\n## `autoparams-lombok`\n\n`autoparams-lombok` is an extension for AutoParams that enhances compatibility with [Project Lombok](https://projectlombok.org/), a popular Java library for reducing boilerplate code.\n\n### Install\n\n#### Maven\n\nFor Maven, you can add the following dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.autoparams\u003c/groupId\u003e\n  \u003cartifactId\u003eautoparams-lombok\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle\n\nFor Gradle, use:\n\n```groovy\ntestImplementation 'io.github.autoparams:autoparams-lombok:11.3.2'\n```\n\n### `BuilderCustomizer` Class\n\nIf you're using Lombok's `@Builder` annotation, the `BuilderCustomizer` allows AutoParams to generate arbitrary objects via the builder, making it easier to write tests without manually constructing instances.\n\nSuppose you have an `Order` class like this:\n\n```java\n@Builder\n@Getter\npublic class Order {\n\n    private final UUID id;\n    private final UUID productId;\n    private final Integer quantity;\n    private final UUID customerId;\n    private final BigDecimal orderedPriceAmount;\n    private final String comment;\n}\n```\n\nTo automatically generate `Order` instances, apply `BuilderCustomizer` in your test:\n\n```java\n@Test\n@AutoParams\n@Customization(BuilderCustomizer.class)\nvoid testMethod(Order order) {\n    assertThat(order.getId()).isNotNull();\n    assertThat(order.getProductId()).isNotNull();\n    assertThat(order.getQuantity()).isNotNull();\n    assertThat(order.getQuantity()).isPositive();\n    assertThat(order.getCustomerId()).isNotNull();\n    assertThat(order.getOrderedPriceAmount()).isNotNull();\n    assertThat(order.getComment()).isNotNull();\n}\n```\n\nThis eliminates the need to manually configure builder calls, helping you write cleaner and more maintainable tests.\n\n#### Custom Method Names\n\nIf your class uses custom builder method names via Lombok's `builderMethodName` and `buildMethodName` attributes, you can still use `BuilderCustomizer` by extending it to specify those method names.\n\nFor example, consider the following `Shipment` class:\n\n```java\n@Builder(builderMethodName = \"getBuilder\", buildMethodName = \"create\")\n@Getter\npublic class Shipment {\n\n    private final UUID id;\n    private final UUID orderId;\n    private final String postalCode;\n    private final String address;\n    private final Boolean shipped;\n}\n```\n\nTo make this compatible with AutoParams, define a custom subclass:\n\n```java\npublic class ShipmentBuilderCustomizer extends BuilderCustomizer {\n\n    public ShipmentBuilderCustomizer() {\n        super(\"getBuilder\", \"create\");\n    }\n}\n```\n\nThen apply it in your test:\n\n```java\n@Test\n@AutoParams\n@Customization(ShipmentBuilderCustomizer.class)\nvoid testMethod(Shipment shipment) {\n    assertThat(shipment.getId()).isNotNull();\n    assertThat(shipment.getOrderId()).isNotNull();\n    assertThat(shipment.getPostalCode()).isNotNull();\n    assertThat(shipment.getAddress()).isNotNull();\n    assertThat(shipment.getShipped()).isNotNull();\n}\n```\n\nThis allows you to use custom builder patterns while still benefiting from automatic object generation.\n\n## `autoparams-kotlin`\n\n`autoparams-kotlin` is an extension of AutoParams that adds Kotlin-specific support for test data generation. It helps reduce boilerplate in Kotlin tests by generating values in a way that aligns with Kotlin’s language features.\n\n### Install\n\n#### Maven\n\nFor Maven, you can add the following dependency to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.autoparams\u003c/groupId\u003e\n  \u003cartifactId\u003eautoparams-kotlin\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle (Groovy)\n\nFor Gradle-Groovy, use:\n\n```groovy\ntestImplementation 'io.github.autoparams:autoparams-kotlin:11.3.2'\n```\n\n#### Gradle (Kotlin)\n\nFor Gradle-Kotlin, use:\n\n```kotlin\ntestImplementation(\"io.github.autoparams:autoparams-kotlin:11.3.2\")\n```\n\n### `@AutoKotlinParams` Annotation\n\nConsider the following Kotlin data class:\n\n```kotlin\ndata class Point(val x: Int = 0, val y: Int = 0)\n```\n\nUsing default values in tests can result in limited test coverage. The `@AutoKotlinParams` annotation enables AutoParams to provide randomized arguments for Kotlin test methods, ensuring more varied and meaningful input.\n\nHere's an example:\n\n```kotlin\n@Test\n@AutoKotlinParams\nfun testMethod(point: Point) {\n    assertThat(point.x).isNotEqualTo(0)\n    assertThat(point.y).isNotEqualTo(0)\n}\n```\n\nIn this test, the `point` parameter is automatically initialized with non-default, randomly generated values—allowing the test to cover a broader range of scenarios without requiring manual setup.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautoparams%2Fautoparams","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautoparams%2Fautoparams","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautoparams%2Fautoparams/lists"}