Skip to main content
Version: v1.1.x

Tips for Beginners

Essential Tips for Using Fixture Monkey

1. Use Type-Safe Methods

  • Prefer type-safe methods over string-based ones
  • Example:
// Instead of
.set("price", 1000L)

// Use
.set(javaGetter(Product::getPrice), 1000L)

2. Use Meaningful Test Data

  • Use values that make sense in your test context
  • Avoid using arbitrary values like "test" or "123"
  • Consider business rules and constraints when setting values
  • Benefits:
    • Makes tests more readable and self-documenting
    • Helps identify test failures more quickly
    • Makes it easier to understand test scenarios
    • Reduces the need for additional comments
  • Example:
// Use meaningful values
Product product = fixtureMonkey.giveMeBuilder(Product.class)
.set("price", 1000L) // Use realistic price that matches business rules
.set("name", "Premium Product") // Use descriptive name that indicates product type
.set("category", "ELECTRONICS") // Use valid category from your domain
.set("stock", 50) // Use reasonable stock quantity
.sample();

3. Keep Tests Readable

  • Add comments to explain why specific values are set
  • Example:
Product product = fixtureMonkey.giveMeBuilder(Product.class)
.set("price", 2000L) // Price above discount threshold
.set("category", "PREMIUM") // Category that gets special treatment
.sample();

4. Handle Collections Properly

  • Set collection size before accessing specific indices
  • Example:
Product product = fixtureMonkey.giveMeBuilder(Product.class)
.size("options", 3) // Set size first
.set("options[1]", "red") // Then access specific index
.sample();

5. Reuse FixtureMonkey Instance

  • Create one instance and reuse it across tests
  • Example:
public class ProductTest {
private static final FixtureMonkey FIXTURE_MONKEY = FixtureMonkey.builder()
.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
.build();

@Test
void test1() {
Product product = FIXTURE_MONKEY.giveMeBuilder(Product.class).sample();
// ...
}

@Test
void test2() {
Product product = FIXTURE_MONKEY.giveMeBuilder(Product.class).sample();
// ...
}
}

6. Reuse ArbitraryBuilder

  • Reuse ArbitraryBuilder instances to maintain consistent test data structure
  • Share common configurations across multiple tests
  • Improve code readability by centralizing test data setup
  • Example:
public class ProductTest {
private static final FixtureMonkey FIXTURE_MONKEY = FixtureMonkey.builder()
.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
.build();

// Base configuration for premium products
private static final ArbitraryBuilder<Product> PREMIUM_PRODUCT_BUILDER = FIXTURE_MONKEY.giveMeBuilder(Product.class)
.set("category", "PREMIUM")
.set("price", 1000L);

@Test
void testDiscountForPremiumProduct() {
// Test discount for premium product with price above threshold
Product product = PREMIUM_PRODUCT_BUILDER
.set("price", 2000L) // Price above discount threshold
.sample();
// Test discount logic
}

@Test
void testShippingForPremiumProduct() {
// Test shipping for premium product with minimum order amount
Product product = PREMIUM_PRODUCT_BUILDER
.set("price", 5000L) // Price above free shipping threshold
.sample();
// Test shipping logic
}
}

7. Start with Simple Objects

  • Begin with basic objects before moving to complex ones
  • Example:
public class ProductTest {
private static final FixtureMonkey FIXTURE_MONKEY = FixtureMonkey.builder()
.objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE)
.build();

@Test
void testBasicProduct() {
// Start with a simple object
Product product = FIXTURE_MONKEY.giveMeBuilder(Product.class)
.set("name", "Test Product")
.sample();
// ...
}
}

8. Use the IntelliJ Plugin

Install the Fixture Monkey Helper plugin to enhance your development experience:

  • Smart code completion for Fixture Monkey methods
  • Type-safe field access suggestions using method references
  • Quick navigation to field definitions
  • Automatic import suggestions for Fixture Monkey classes
  • Real-time validation of field names and types

9. Common Use Cases

  • Testing validation rules
  • Testing business logic with specific conditions
  • Creating test data for integration tests
  • Generating random but valid test data

10. Best Practices

  • Keep test data generation close to where it's used
  • Use meaningful variable names
  • Document complex test scenarios
  • Use constants for frequently used values