Model or dataset
naver/fixture-monkey avatar
naver/fixture-monkey

Fixture Monkey: random test objects with path expressions for the fields that matter

Let Fixture Monkey generates fully-customizable, randomly populated instance. Focus on the properties of the class that really matter in your test.

700 stars127 forksJavaApache-2.0

At a glance

What is it?
Fixture Monkey is a Java and Kotlin library that generates test objects on demand and lets you pin individual nested fields with path expressions, leaving everything else random. It is Apache 2.0 licensed, published to Maven Central, and it ships a Claude Code plugin so an agent writes tests the way the library expects.
Who is it for?
Adopt Fixture Monkey when your JVM tests are drowning in setter boilerplate and you want random values everywhere except the two or three fields that determine the outcome, since path expressions give you exactly that control. Do not adopt it if your test style depends on fully deterministic data, because the default is random by design and pinning every field by hand reintroduces the boilerplate it removes.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 25 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem: test objects made of setters

The README frames the library with a before and after that is worth reading as a design statement. Before, test object creation is manual: instantiate the class, set the id, set the name, and continue through many more setters. After, it is one call, fixtureMonkey.giveMeOne(Product.class). The tagline at the top is write once, test anywhere, and the description says the library is designed to generate controllable arbitrary test objects. The word controllable is the important one, because the naive alternative, generating purely random objects, produces tests that are hard to reason about. Fixture Monkey's stated most distinctive feature is the ability to freely access and configure any nested fields through path-based expressions, and the stated purpose is to simplify test writing by facilitating the generation of necessary test fixtures, making JVM tests more concise and safe.

Path expressions are the core idea

The path expression mechanism is what separates this from a random value generator. The README shows a single expression that sets the name of the product inside every item of the order's item list, which it calls intuitive path-based configuration, and it says this lets you configure any nested field with a single line instead of endless getter and setter chains. The wildcard in the path is doing the real work: it addresses a collection of nested objects rather than one named instance, so a change in the shape of the domain model does not require rewriting a chain of calls. The library also handles inheritance and circular references, so from simple POJOs to complex object graphs the same entry point works, and the README notes it is even usable with circular references in mind rather than being limited to flat structures.

Adding the dependency, and the first generated object

The library is published to Maven Central under the com.navercorp.fixturemonkey group, with a starter artifact for Java and one for Kotlin. The current version in the README examples is 1.2.3, matching the 1.2.3 release tag dated 2026-09-07.

java
FixtureMonkey fixtureMonkey = FixtureMonkey.create();
Product product = fixtureMonkey.giveMeOne(Product.class);

The Kotlin form uses the generic giveMeOne<Product>() on a FixtureMonkey.create() instance. The README also states one non-obvious requirement: when using Lombok with Fixture Monkey you should add lombok.anyConstructor.addConstructorProperties=true in lombok.config, because the library needs to know which constructor arguments to use.

xml
<dependency>
    <groupId>com.navercorp.fixturemonkey</groupId>
    <artifactId>fixture-monkey-starter</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>

The Kotlin artifact is the same with fixture-monkey-starter-kotlin in the artifactId, and the Gradle form is a testImplementation line for the matching artifact. Once the dependency is in place, the first object is one line in either language.

The builder API, and why one introspector is specified

The builder form exists for when the default constructor is not the one you want, and the README example shows why you often need it. The Java example builds a FixtureMonkey with the objectIntrospector set to ConstructorPropertiesArbitraryIntrospector.INSTANCE, then uses giveMeBuilder with set calls on javaGetter expressions, a minSize call on the items list, and finally sample. The Kotlin example registers the KotlinPlugin instead and uses setExp and minSizeExp. Both styles end with assertions on the three pinned properties, and the Kotlin one asserts that the items collection has at least one element. The introspector choice is the part that bites: Fixture Monkey has to pick a constructor, and where a class has several, you choose which one it populates rather than letting the library guess.

Reusable specifications, and the size controls

The third reason to use the library in the README is reusable test specifications, and the mechanism is straightforward. You build an ArbitraryBuilder once with the constraints that matter, keep the builder, and call sample on it as many times as you need. The example defines a product builder that sets the category to Book and the price to 1000, then samples it in two different tests, the second adding a size call for the reviews collection. That distinction between the builder and the sample matters in practice: a builder is a specification you can share across a test class, a sample is one instance, and separating them is what removes the duplication the feature is aimed at. The size and minSize calls cover the other common need, which is a collection that must be non-empty or must contain exactly n elements, rather than the empty case a generator would otherwise produce.

Optional integrations, one module at a time

The repository layout shows that Fixture Monkey is a family of modules rather than one jar, and that matters for dependency hygiene. The core modules are fixture-monkey, fixture-monkey-api, fixture-monkey-engine, fixture-monkey-starter and fixture-monkey-starter-kotlin, and object-farm-api sits alongside as the arbitraries layer. On top of that there are integration modules for each ecosystem you might use: fixture-monkey-junit-jupiter, fixture-monkey-kotest, fixture-monkey-mockito, fixture-monkey-jackson and fixture-monkey-jackson3 for JSON binding, fixture-monkey-javax-validation and fixture-monkey-jakarta-validation for bean validation, fixture-monkey-datafaker for generating values from the Faker data sets, fixture-monkey-kotlin and fixture-monkey-autoparams, which is the JUnit 5 parameterised test source, plus fixture-monkey-benchmarks and fixture-monkey-tests. You add only the integrations your test suite actually uses, and the starter artifacts pull in the parts you need.

A Claude Code plugin that teaches the agent the house style

The most recent addition is aimed squarely at the way AI coding assistants write tests. The README says Fixture Monkey ships a Claude Code plugin that teaches the agent to write tests the way the library intends, and it describes the intended behaviour in a way that is a design principle in its own right: enumerate the cases a method can produce, keep the ones worth testing, and pin only the properties that force the expected outcome, leaving everything else random so the test stays out of unrelated diffs. The plugin is installed with one line.

bash
claude plugin marketplace add naver/fixture-monkey --sparse .claude-plugin claude-plugins && claude plugin install fixture-monkey@fixture-monkey

After that you ask for tests and the skill activates on its own, with the /fixture-monkey:write-fixture command invoking it explicitly. Two notes in the README matter in practice: the --sparse flag limits the checkout to the plugin directories instead of cloning the whole library, and the naver/fixture-monkey shorthand clones over SSH by default, so if Git SSH is not set up you prefix the command with CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1. The plugin only teaches the agent; the library itself still has to be added to your build.

Rules for other agents, and the limits of the approach

The same guidance is published as plain documentation for tools that are not Claude Code, and the README points your Cursor rule, AGENTS.md or Copilot instructions file at two URLs, one for writing tests and one for the API reference, with an AI Agents guide covering the full procedure. That the maintainers treat this as a general rule set rather than a plugin detail says something about where the friction was. The broader limit of the library follows from its premise, and the README is honest about it in the plugin description: if you pin every field, you are back to writing the object by hand, and if you pin nothing, the test says nothing. The method that works is enumerating the meaningful cases and pinning the property that decides the outcome, which is a discipline the library cannot enforce for you. There is also a maintenance question behind the tooling, since the project publishes frequent patch releases, 1.2.3, 1.2.2 and 1.1.23 all dated 2026-09-07, and the last push was on 2026-09-28. The licence is Apache 2.0 with the LICENSE file in the root, and the project is published under the naver organisation, whose README is written in Korean and Chinese alongside the English text.

Editorial conclusion

Adopt Fixture Monkey when your JVM tests are drowning in setter boilerplate and you want random values everywhere except the two or three fields that determine the outcome, since path expressions give you exactly that control. Do not adopt it if your test style depends on fully deterministic data, because the default is random by design and pinning every field by hand reintroduces the boilerplate it removes. Before you adopt it, check how your domain types are constructed, since the README shows an explicit introspector and a Lombok configuration note, and decide whether you want the optional plugins such as the Jakarta validation, Jackson, Mockito, Kotest or Datafaker integrations, each of which is a separate module in the repository.

Frequently asked questions

What is Fixture Monkey and what problem does it solve?

It is a Java and Kotlin library designed to generate controllable arbitrary test objects, so that test fixture creation stops being a block of setters. Its most distinctive feature is the ability to freely access and configure any nested fields through path-based expressions, and it is published to Maven Central under com.navercorp.fixturemonkey.

How do I add Fixture Monkey to a Gradle or Maven project?

The README shows testImplementation lines for fixture-monkey-starter and fixture-monkey-starter-kotlin at version 1.2.3, and the equivalent Maven dependencies with test scope for the same artifacts. The current version in the examples matches the 1.2.3 release tag dated 2026-09-07.

How do I set a nested field with Fixture Monkey?

You use a path expression on the builder, for example setting items[*].product.name to set the product name inside every item of the order. The README describes this as intuitive path-based configuration that configures any nested field with a single line instead of getter and setter chains.

Does Fixture Monkey work with Lombok?

The README notes you should add lombok.anyConstructor.addConstructorProperties=true in lombok.config when using Lombok with Fixture Monkey. The Java example also sets the objectIntrospector to ConstructorPropertiesArbitraryIntrospector.INSTANCE when building the FixtureMonkey instance.

What does the Fixture Monkey Claude Code plugin do?

The README says the plugin teaches the agent to write tests the way the library intends: enumerate the cases a method can produce, keep the ones worth testing, and pin only the properties that force the expected outcome, leaving everything else random. It is installed with the claude plugin marketplace add and claude plugin install command shown in the README.

Official sources

  1. License: Apache-2.0
  2. naver/fixture-monkey on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/naver-fixture-monkey.svg)](https://hysenlabs.com/projects/naver-fixture-monkey)

Was this useful?