๐Ÿ”ท Core

bx-web-support

Use this skill for testing web-context code outside a web server in BoxLang with bx-web-support: mockServerGet/Post/Put/Delete/Patch, mockRequestNew, mockRequestRun, setting request headers/body/path, and testing handlers that depend on getHTTPRequestData(), form scope, URL scope, and other web BIFs.

$ npx skills add ortus-boxlang/skills/boxlang-modules/bx-web-support
$ coldbox ai skills install ortus-boxlang/skills/boxlang-modules/bx-web-support
๐Ÿ”— https://skills.boxlang.io/skills/raw/ortus-boxlang/skills/boxlang-modules~bx-web-support

bx-web-support: Web Context Mocking for Testing

BoxLang is the AI-native software productivity platform for building, modernizing and running applications, with developers and AI agents working together.

Installation

install-bx-module bx-web-support
# CommandBox
box install bx-web-support

IMPORTANT: This module is for CLI and testing only. Do NOT install it in a web runtime โ€” it will cause JAR conflicts with the web server's request handling. It should be installed as a test/development dependency only.

Purpose

bx-web-support lets you simulate HTTP requests and web contexts when running BoxLang scripts in CLI mode or unit tests. This allows you to test handlers and components that rely on web-specific BIFs like getHTTPRequestData(), form, url, CGI, and request scopes.

BIFs

BIFDescription
mockServerGet( path )Create a mock GET request
mockServerPost( path )Create a mock POST request
mockServerPut( path )Create a mock PUT request
mockServerDelete( path )Create a mock DELETE request
mockServerPatch( path )Create a mock PATCH request
mockRequestNew()Create a blank request builder
mockRequestRun( request )Execute the mock request and return a response

Fluent Request Builder

All mockServer*() BIFs return a fluent request builder with the following methods:

MethodDescription
.setRequestMethod( method )Override the HTTP method
.setRequestPath( path )Set the request path
.addRequestHeader( name, value )Add a request header
.setRequestBody( bodyString )Set the request body (JSON, form-encoded, etc.)
.addQueryParam( name, value )Add a URL query parameter
.addFormField( name, value )Add a form field (for POST)
.run()Execute the request and return the response

Basic Usage

Simulating a GET Request

// Simulate GET /api/users?status=active
response = mockServerGet( "/api/users" )
    .addQueryParam( "status", "active" )
    .addRequestHeader( "Accept", "application/json" )
    .run()

writeOutput( response.statusCode )   // 200
writeOutput( response.body )         // JSON response body

Simulating a POST with JSON Body

response = mockServerPost( "/api/users" )
    .addRequestHeader( "Content-Type", "application/json" )
    .addRequestHeader( "Authorization", "Bearer mytoken123" )
    .setRequestBody( serializeJSON({ name: "Alice", email: "[email protected]" }) )
    .run()

writeOutput( response.statusCode )   // 201
var result = deserializeJSON( response.body )

Simulating a PUT Request

response = mockServerPut( "/api/users/42" )
    .addRequestHeader( "Content-Type", "application/json" )
    .setRequestBody( serializeJSON({ name: "Alice Updated" }) )
    .run()

Simulating a Form POST

response = mockServerPost( "/login" )
    .addFormField( "username", "alice" )
    .addFormField( "password", "secret123" )
    .addRequestHeader( "Content-Type", "application/x-www-form-urlencoded" )
    .run()

Inside the Handler (Web Context Available)

When a mock request is running, the full web context is available inside your handler:

// Your handler code (handler.bx)
function handleRequest() {
    var requestData = getHTTPRequestData()   // Contains body, method, headers
    var payload     = deserializeJSON( requestData.content )
    var authHeader  = requestData.headers[ "Authorization" ] ?: ""

    url.status  // Available from query params set via addQueryParam()
    form.name   // Available from form fields set via addFormField()
}

Testing in TestBox

component extends="testbox.system.BaseSpec" {

    function run() {
        describe( "UsersAPI", () => {

            it( "returns 200 for GET /api/users", () => {
                var response = mockServerGet( "/api/users" )
                    .addRequestHeader( "Accept", "application/json" )
                    .run()

                expect( response.statusCode ).toBe( 200 )
                var body = deserializeJSON( response.body )
                expect( body ).toBeTypeOf( "array" )
            })

            it( "creates a user via POST /api/users", () => {
                var response = mockServerPost( "/api/users" )
                    .addRequestHeader( "Content-Type", "application/json" )
                    .setRequestBody( serializeJSON({ name: "Test User", email: "[email protected]" }) )
                    .run()

                expect( response.statusCode ).toBe( 201 )
                var body = deserializeJSON( response.body )
                expect( body.id ).notToBeEmpty()
            })

            it( "returns 404 for unknown resource", () => {
                var response = mockServerGet( "/api/nonexistent" ).run()
                expect( response.statusCode ).toBe( 404 )
            })

        })
    }
}

box.json: Test-Only Dependency

{
  "devDependencies": {
    "bx-web-support": "*"
  }
}

Common Pitfalls

  • โŒ Never install bx-web-support in a production web runtime โ€” it conflicts with the real web server adapters
  • โœ… Install as a dev/test dependency (devDependencies in box.json) so it isn't bundled in production
  • โœ… Use mockServerPost + addFormField for simulating form submissions (not setRequestBody)
  • โœ… Use mockServerPost + setRequestBody for JSON API requests
  • โŒ mockRequestNew() creates a blank request with no method or path set โ€” use the named helpers instead
  • โœ… The web context (form, url, CGI, getHTTPRequestData) is fully populated during request execution