FixtureMonkey
What is FixtureMonkey?
FixtureMonkey is the main entry point for creating test fixtures in the Fixture Monkey library. Think of it as a factory that knows how to create instances of any class with random but valid values. This makes it perfect for generating test data without writing verbose setup code.
How it works - A quick overview
The typical workflow with Fixture Monkey looks like this:
- Create a
FixtureMonkeyinstance - Use one of its generation methods to create test objects
- Optionally customize the objects to match specific test requirements
For example, here's a complete test using Fixture Monkey:
- Java
- Kotlin
@Test
void testProductDiscount() {
// 1. Create a FixtureMonkey instance
FixtureMonkey fixtureMonkey = FixtureMonkey.create();
// 2. Generate a test object with specific properties
Product product = fixtureMonkey.giveMeBuilder(Product.class)
.set("price", 100.0)
.sample();
// 3. Use the object in your test
double discountedPrice = productService.applyDiscount(product, 10);
// 4. Assert the expected outcome
assertEquals(90.0, discountedPrice);
}
@Test
fun testProductDiscount() {
// 1. Create a FixtureMonkey instance
val fixtureMonkey = FixtureMonkey.plugin(KotlinPlugin()).build()
// 2. Generate a test object with specific properties
val product: Product = fixtureMonkey.giveMeBuilder<Product>()
.set("price", 100.0)
.sample()
// 3. Use the object in your test
val discountedPrice = productService.applyDiscount(product, 10)
// 4. Assert the expected outcome
assertEquals(90.0, discountedPrice)
}
Now let's learn the specific steps to use FixtureMonkey in your tests.
Creating a FixtureMonkey Instance
To generate test fixtures, the first step is to create a FixtureMonkey instance, which facilitates the creation of test fixtures.
You can use the create() method to generate a FixtureMonkey instance with default options.
For Kotlin environments, add the Kotlin plugin.
- Java
- Kotlin
FixtureMonkey fixtureMonkey = FixtureMonkey.create();
val fixtureMonkey = FixtureMonkey
.plugin(KotlinPlugin())
.build()
If you want to add some options for creating or customizing the test fixtures, you can add them using the FixtureMonkey builder.
- Java
- Kotlin
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
+ options...
.build();
val fixtureMonkey = FixtureMonkey.builder()
+ options...
.build()
For information on what options are available, see the Fixture Monkey Options section.
Generating instances
The FixtureMonkey class provides several methods to help create test objects of the required type.
When to use which method?
Here's a quick guide to help you choose the right method:
giveMeOne()- When you need a single instance with default random valuesgiveMe()- When you need multiple instances with default random valuesgiveMeBuilder()- When you need to customize properties before creating instancesgiveMeArbitrary()- Advanced usage when working with jqwik's Arbitrary API
giveMeOne()
If you need an instance of a certain type, you can use giveMeOne(). Pass either a class or a type reference.
- Java
- Kotlin
Product product = fixtureMonkey.giveMeOne(Product.class);
List<String> strList = fixtureMonkey.giveMeOne(new TypeReference<List<String>>() {});
then(product).isNotNull();
then(strList).isNotNull();
val product: Product = fixtureMonkey.giveMeOne()
val strList: List<String> = fixtureMonkey.giveMeOne()
then(product).isNotNull
then(strList).isNotNull
giveMe()
If you need multiple instances of a certain type, you can use the giveMe() method.
You can choose to generate either a stream of instances or a list by specifying the desired size.
- Java
- Kotlin
Stream<Product> productStream = fixtureMonkey.giveMe(Product.class);
Stream<List<String>> strListStream = fixtureMonkey.giveMe(new TypeReference<List<String>>() {});
List<Product> productList = fixtureMonkey.giveMe(Product.class, 3);
List<List<String>> strListList = fixtureMonkey.giveMe(new TypeReference<List<String>>() {}, 3);
then(productStream).isNotNull();
then(strListStream).isNotNull();
then(productList).hasSize(3);
then(strListList).hasSize(3);
val productSequence: Sequence<Product> = fixtureMonkey.giveMe()
val strListSequence: Sequence<List<String>> = fixtureMonkey.giveMe()
val productList: List<Product> = fixtureMonkey.giveMe<Product>(3).toList()
val strListList: List<List<String>> = fixtureMonkey.giveMe<List<String>>(3).toList()
then(productSequence).isNotNull
then(strListSequence).isNotNull
then(productList).hasSize(3)
then(strListList).hasSize(3)
giveMeBuilder()
If you need to further customize the instance to be created, you can use giveMeBuilder(). This will return an ArbitraryBuilder of the given type.
An ArbitraryBuilder is a class in Fixture Monkey that acts as a builder for an Arbitrary object of the given class.
- Java
- Kotlin
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(Product.class);
ArbitraryBuilder<List<String>> strListBuilder = fixtureMonkey.giveMeBuilder(new TypeReference<List<String>>() {});
then(productBuilder.sample()).isNotNull();
then(strListBuilder.sample()).isNotNull();
val productBuilder = fixtureMonkey.giveMeBuilder<Product>()
val strListBuilder = fixtureMonkey.giveMeBuilder<List<String>>()
then(productBuilder.sample()).isNotNull
then(strListBuilder.sample()).isNotNull
For cases where you already have a generated instance and want to customize it further, you can also use giveMeBuilder().
- Java
- Kotlin
Product product = new Product(1L, "Book", 9.99);
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(product);
then(productBuilder.sample()).isNotNull();
val product = Product(1L, "Book", 9.99)
val productBuilder = fixtureMonkey.giveMeBuilder(product)
then(productBuilder.sample()).isNotNull
The generated ArbitraryBuilder can be used for further customization of your fixture. For more information on customization options, see the section on customization objects.
To obtain an instance from the ArbitraryBuilder, you can use the sample(), sampleList(), sampleStream() methods of the ArbitraryBuilder.
- Java
- Kotlin
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(Product.class);
Product product = productBuilder.sample();
List<Product> productList = productBuilder.sampleList(3);
Stream<Product> productStream = productBuilder.sampleStream();
then(product).isNotNull();
then(productList).hasSize(3);
then(productStream).isNotNull();
val productBuilder = fixtureMonkey.giveMeBuilder<Product>()
val product = productBuilder.sample()
val productList = productBuilder.sampleList(3)
val productStream = productBuilder.sampleStream()
then(product).isNotNull
then(productList).hasSize(3)
then(productStream).isNotNull
In cases where you need an Arbitrary itself rather than an instance, you can simply call the build() method.
- Java
- Kotlin
Product product = fixtureMonkey.giveMeOne(Product.class);
List<String> strList = fixtureMonkey.giveMeOne(new TypeReference<List<String>>() {});
then(product).isNotNull();
then(strList).isNotNull();
}
@Test
void giveMe() {
Stream<Product> productStream = fixtureMonkey.giveMe(Product.class);
Stream<List<String>> strListStream = fixtureMonkey.giveMe(new TypeReference<List<String>>() {});
List<Product> productList = fixtureMonkey.giveMe(Product.class, 3);
List<List<String>> strListList = fixtureMonkey.giveMe(new TypeReference<List<String>>() {}, 3);
then(productStream).isNotNull();
then(strListStream).isNotNull();
then(productList).hasSize(3);
then(strListList).hasSize(3);
}
@Test
void giveMeBuilder() {
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(Product.class);
ArbitraryBuilder<List<String>> strListBuilder = fixtureMonkey.giveMeBuilder(new TypeReference<List<String>>() {});
then(productBuilder.sample()).isNotNull();
then(strListBuilder.sample()).isNotNull();
}
@Test
void giveMeBuilderWithInstance() {
Product product = new Product(1L, "Book", 9.99);
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(product);
then(productBuilder.sample()).isNotNull();
}
@Test
void obtainInstances() {
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(Product.class);
Product product = productBuilder.sample();
List<Product> productList = productBuilder.sampleList(3);
Stream<Product> productStream = productBuilder.sampleStream();
then(product).isNotNull();
then(productList).hasSize(3);
then(productStream).isNotNull();
}
@Test
void build() {
ArbitraryBuilder<Product> productBuilder = fixtureMonkey.giveMeBuilder(Product.class);
Arbitrary<Product> productArbitrary = productBuilder.build();
then(productArbitrary).isNotNull();
}
@Test
void giveMeArbitrary() {
Arbitrary<Product> productArbitrary = fixtureMonkey.giveMeArbitrary(Product.class);
Arbitrary<List<String>> strListArbitrary = fixtureMonkey.giveMeArbitrary(new TypeReference<List<String>>() {});
then(productArbitrary).isNotNull();
then(strListArbitrary).isNotNull();
}
val product: Product = fixtureMonkey.giveMeOne()
val strList: List<String> = fixtureMonkey.giveMeOne()
then(product).isNotNull
then(strList).isNotNull
}
@Test
fun giveMe() {
val productSequence: Sequence<Product> = fixtureMonkey.giveMe()
val strListSequence: Sequence<List<String>> = fixtureMonkey.giveMe()
val productList: List<Product> = fixtureMonkey.giveMe<Product>(3).toList()
val strListList: List<List<String>> = fixtureMonkey.giveMe<List<String>>(3).toList()
then(productSequence).isNotNull
then(strListSequence).isNotNull
then(productList).hasSize(3)
then(strListList).hasSize(3)
}
@Test
fun giveMeBuilder() {
val productBuilder = fixtureMonkey.giveMeBuilder<Product>()
val strListBuilder = fixtureMonkey.giveMeBuilder<List<String>>()
then(productBuilder.sample()).isNotNull
then(strListBuilder.sample()).isNotNull
}
@Test
fun giveMeBuilderWithInstance() {
val product = Product(1L, "Book", 9.99)
val productBuilder = fixtureMonkey.giveMeBuilder(product)
then(productBuilder.sample()).isNotNull
}
@Test
fun obtainInstances() {
val productBuilder = fixtureMonkey.giveMeBuilder<Product>()
val product = productBuilder.sample()
val productList = productBuilder.sampleList(3)
val productStream = productBuilder.sampleStream()
then(product).isNotNull
then(productList).hasSize(3)
then(productStream).isNotNull
}
@Test
fun build() {
val productBuilder = fixtureMonkey.giveMeBuilder<Product>()
val productArbitrary = productBuilder.build()
then(productArbitrary).isNotNull
}
@Test
fun giveMeArbitrary() {
val productArbitrary = fixtureMonkey.giveMeArbitrary<Product>()
val strListArbitrary = fixtureMonkey.giveMeArbitrary<List<String>>()
then(productArbitrary).isNotNull
then(strListArbitrary).isNotNull
}
giveMeArbitrary()
To get an Arbitrary of the specified type, you can use the giveMeArbitrary() method.
- Java
- Kotlin
Arbitrary<Product> productArbitrary = fixtureMonkey.giveMeArbitrary(Product.class);
Arbitrary<List<String>> strListArbitrary = fixtureMonkey.giveMeArbitrary(new TypeReference<List<String>>() {});
then(productArbitrary).isNotNull();
then(strListArbitrary).isNotNull();
val productArbitrary = fixtureMonkey.giveMeArbitrary<Product>()
val strListArbitrary = fixtureMonkey.giveMeArbitrary<List<String>>()
then(productArbitrary).isNotNull
then(strListArbitrary).isNotNull