Skip to content

A First Simple Example

This chapter demonstrates the most common workflow in Moxter: executing a basic HTTP request and capturing data from the response to use later in your test suite.


The YAML Definition

Place a file named fixtures.yaml in your test resources (e.g., src/test/resources/moxter/simple/). This file describes the "what"—the declarative state of your HTTP call.

fixtures:            # aka 'moxtures'
  - name: create_pet
    method: POST
    endpoint: /api/pets
    expectedStatus: 201   # make call fail if return status is different
    payload:
      firstName: "Thomas "
      lastName: "O'Malley"
      address: "Alleyways and rooftops"
      city: "Paris"
    save:
      petId: $.id    # Capture the 'id' field from the JSON response body
                     # (using JSonPath syntax) so it can be used either in 
                     # another fixture, or inside the JUnit test.


  - name: apply_approved_shampoo
    method: POST
    endpoint: /api/pet/{{petId}}/shampoo  # We're re-using the petId from the 
                                          # fixture above. 
    expectedStatus: 201
    payload:
      type: "herbal type 3"
      strength: "mild"
      duration: "5 min"
      rinse: "warm"
    save:
      petVitals: $.vitals    # Info on how the pet responds to the shampoo


  # Orchestrating a scenario by grouping fixtures
  - name: all_in_one_shampoo
    fixtures:      # Calling this fixture will result in the chained execution of 
                   # the following fixtures, in the given order:
       - create_pet
       - apply_herbal_shampoo
       # add any other desired fixture





The Java JUnit test

In your JUnit test, you build the engine and call the fixture by its symbolic name. Moxter handles the MockMvc execution, JSON serialization, and status assertions automatically.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
class PetIntegrationTest {

    @Autowired
    private MockMvc mockMvc; // Injected by the Spring Test context

    private static Moxter mx;  // Our fixture engine

    @BeforeAll
    static void setup(@Autowired MockMvc mockMvc) {
        // Build the engine for this test class
        mx = Moxter.forTestClass(PetIntegrationTest.class)  
                    // (this will let Moxter know which fixture file(s) to load)
                   .mockMvc(mockMvc)
                   .build();
    }

    @Test
    @DisplayName("Make sure shampoo that says it's approved, does not irritate pet's skin")
    void testShampooOnPet() {

        // 1. First we'll need a pet => execute the dedicated fixture defined in the fixture file: 
        mx.callFixture("create_pet");

        // 2. Optional: Access captured variables directly:
        Long newId = mx.varsGetLong("ownerId");
        assertNotNull(newId, "The pet ID should have been captured from the response");

        // 3. Then we'll apply the shampoo on the created pet.
        //    Thanks to chaining, the pet id is automatically passed to 
        //    the 'shampoo' fixture.
        mx.callFixture("apply_approved_shampoo");

        // 4. Retrieve the return captured by Moxter:
        Map<String, Object> vitals = mx.varsGet("petVitals", Map.class)

        // 5. Perform standard JUnit/AssertJ assertions on the pet's health:
        assert(vitals.get("temperature")).inBetween("35 °C").and("40 °C");
        assertThat(vitals.get("heartRate")).inBetween("50").and("150");
        assert(vitals.get("fur")) ... ;
        ...

    }
}


How it Works

Moxter acts as a coordination layer between your declarative YAML files and the Spring MockMvc framework.

  • Discovery: The engine finds the fixtures.yaml based on your test's package name.
  • Resolution: Any placeholders like {{var}} in the YAML are replaced by values currently in the engine's memory.
  • Assertion: If the server returns anything other than the expectedStatus (201 in this case), the test fails immediately with a descriptive error message showing the response body.
  • Persistence: The save block extracts the ID from the response and stores it in the engine's shared memory, making it available for any subsequent fixture calls or Java assertions.