Generating mocks and examples

Generate OpenAPI response mocks and examples easily.

A quick example

Using the burger shop testing OpenAPI specification, we can generate a mock from one of the examples in Fries component schema.

import (
	"fmt"
	"github.com/pb33f/libopenapi"
	"github.com/pb33f/libopenapi/renderer"
	"os"
)

func renderFries() {

  // create a new JSON mock generator
  mg := renderer.NewMockGenerator(renderer.JSON)

  // tell the mock generator to pretty print the output
  mg.SetPretty()

  burgerShop, _ := os.ReadFile("burgershop.openapi.yaml")

  // create a new document from specification and build a v3 model.
  document, _ := libopenapi.NewDocument(burgerShop)
  v3Model, _ := document.BuildV3Model()

  // create a mock of the Fries model
  friesModel := v3Model.Model.Components.Schemas["Fries"]

  // build the fries schema
  fries := friesModel.Schema()

  // generate a mock of the fries schema
  mock, err := mg.GenerateMock(fries, "")

  if err != nil {
    panic(err)
  }

  // print the mock to stdout
  fmt.Println(string(mock))
}

This will print out the following to the console:

{
  "favoriteDrink": {
    "drinkType": "coke",
    "size": "M"
  },
  "potatoShape": "Crispy Shoestring"
}

Rendering a mock

The MockGenerator struct is used to generate mocks from high-level objects in the libopenapi model. There are a few requirements that need to be met before a mock can be generated.

The high-level object must implement the following three common properties:

  • Example
  • Examples
  • Schema

Here are all the high level objects that implement these properties and can be used with the mock renderer:

Model Package Model Name
base Schema
base SchemaProxy
v3 Header
v3 MediaType
v3 Parameter

How it operates

The renderer will always try and render out examples that are baked into the model. If the examples are not implemented then renderer will attempt to generate a mock from the schema.

The rendered will build out the mock using the Schema object, recursively building out all the properties of the mock, implementing oneOf, allOf, anyOf, dependentSchemas and any other complex types that may be used.

The renderer will attempt to construct example values, based on the schema type, format, pattern and constraints like min/max length. etc.

If the renderer is unable to generate a mock from the schema, it will return an error.

Providing a dictionary

The renderer generates random values from a dictionary of words, to use as mock values. The default dictionary is /usr/share/dict/words, however this can easily be overridden by using the NewMockGeneratorWithDictionary constructor.

mg := renderer.NewMockGeneratorWithDictionary("/path/to/dictionary", renderer.JSON)

A dictionary is just a text file with a word on each line. The renderer will randomly select a word from the dictionary that meets the criteria of the schema.

Generating random data.

When the pattern property of a schema is used, the renderer will try and generate a random value that matches the pattern of the regular expression. Using pattern will really help the renderer generate more consumable mock data for specific data patterns.

Rendering examples

There are more examples available if you’d like to see a few different variations of how to use the mock renderer.

Rendering all properties

If a schema includes required properties, the renderer will attempt to render out all the properties of the schema that are required only.

If you’d like to render out all the properties of a schema, you can use the DisableRequiredCheck() method on the SchemaRenderer struct.

This will instruct the renderer to render all values, regardless of the required properties.