agentsclimarketplace

Testing base classes

Skill ColdBox/skills/coldbox/testing-base-classes

Use this skill to understand which ColdBox testing base class to extend for a given test type, configure test bundle annotations (appMapping, configMapping, unloadColdBox, loadColdBox, coldboxAppKey), set up the tests/ harness (Application.cfc, folder structure), or choose between integration testing (BaseTestCase), isolated handler testing (BaseHandlerTest), model unit testing (BaseModelTest), and interceptor unit testing (BaseInterceptorTest).From its SKILL.md

Install
npx -y skills add ColdBox/skills --skill testing-base-classes

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.7 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it

ColdBox Testing Base Classes

Class Hierarchy

testbox.system.BaseSpec
 └── coldbox.system.testing.BaseTestCase
      ├── coldbox.system.testing.BaseHandlerTest
      ├── coldbox.system.testing.BaseModelTest
      └── coldbox.system.testing.BaseInterceptorTest

Quick Decision Guide

I want to test…Extend
Handler actions using the full virtual app (execute / routes / interceptors)BaseTestCase
Handler CFC in complete isolation (no app load)BaseHandlerTest
A model/service/ORM entity in isolationBaseModelTest
An interceptor CFC in isolationBaseInterceptorTest
Any CFML/BX component with no ColdBox appBaseSpec (TestBox)

Bundle Annotations Reference

All ColdBox test bundles support these annotations:

AnnotationDefaultDescription
appMapping/Slash-notation path to the app root relative to the web root (e.g. /apps/blog)
configMapping{appMapping}/config/Coldbox.cfcDot-notation path to the config CFC
coldboxAppKeycbControllerApplication scope key where the controller is stored
loadColdBoxtrueBoot the virtual ColdBox app in beforeAll
unloadColdBoxtrueDestroy the virtual app in afterAll
class extends="coldbox.system.testing.BaseTestCase"
    appMapping="/apps/blog"
    configMapping="apps.blog.test.resources.Config"
    coldboxAppKey="cbController"
    unloadColdBox="false"
{}

Setting unloadColdBox="false" is a major performance win when multiple bundles share the same app.


Test Harness Structure

CommandBox generates this layout when you run coldbox create app:

tests/
├── Application.cfc          ← harness Application.cfc
├── resources/                ← fixtures, test data, test config
│   └── Config.cfc
└── specs/
    ├── integration/          ← BaseTestCase bundles
    └── unit/
        ├── handlers/         ← BaseHandlerTest bundles
        ├── models/           ← BaseModelTest bundles
        └── interceptors/     ← BaseInterceptorTest bundles

tests/Application.cfc

class {
    this.name               = "ColdBoxTestingSuite"
    this.sessionManagement  = true
    this.sessionTimeout     = createTimeSpan( 0, 0, 15, 0 )
    this.applicationTimeout = createTimeSpan( 0, 0, 15, 0 )
    this.setClientCookies   = true

    // Map the test app root
    this.mappings[ "/root" ] = expandPath( "../" )

    function onRequestStart( string targetPage ) {
        // flush before each request
        if ( structKeyExists( url, "fwreinit" ) ) {
            if ( structKeyExists( server, "lucee" ) ) {
                pagePoolClear()
            }
        }
    }
}

BaseTestCase — Integration

Loads the full virtual ColdBox app. Use for end-to-end handler, route, and cross-layer tests.

class extends="coldbox.system.testing.BaseTestCase"
    appMapping="/root"
    unloadColdBox="false"
{
    function beforeAll() { super.beforeAll() }
    function afterAll()  { super.afterAll()  }

    function run() {
        describe( "My Integration Suite", () => {
            beforeEach( () => { setup() } )  // reset virtual request
            // specs...
        } )
    }
}

Key methods available:

MethodDescription
setup()Reset the virtual request (call in beforeEach)
execute( event, renderResults, ... )Simulate an event (GET-style)
get/post/put/patch/delete( route, params, headers, body )HTTP verb simulation
getInstance( name )Resolve a WireBox object
getController()Access the ColdBox controller
getWireBox()Access the WireBox injector
prepareMock( target )Prepare an object for MockBox

BaseHandlerTest — Isolated Handler Unit

Tests handler CFCs with no app load. You must mock every dependency.

class extends="coldbox.system.testing.BaseHandlerTest" handler="handlers.users" {

    function beforeAll() {
        super.setup()   // note: setup(), not beforeAll()
    }

    function run() {
        describe( "users handler — isolated", () => {
            it( "calls the service", () => {
                var mockSvc = createMock( "models.UserService" )
                handler.$property( propertyName = "userService", mock = mockSvc )
                mockSvc.$( "findAll" ).$results( [] )
                var event = execute( event = "users.index" )
                expect( mockSvc.$once( "findAll" ) ).toBeTrue()
            } )
        } )
    }
}

Available after super.setup():

  • variables.handler — the instantiated handler CFC
  • variables.handlerName — fully-qualified name
  • execute() — runs the handler action
  • prepareMock(), createMock() — MockBox helpers

BaseModelTest — Model / Service Unit

Tests model CFCs in isolation with pre-wired mock helpers. No app load.

class extends="coldbox.system.testing.BaseModelTest" model="models.UserService" {

    function beforeAll() {
        super.setup()
        model.init()   // call your own init if needed
    }

    function run() {
        describe( "UserService — isolated", () => {
            it( "computes something", () => {
                expect( model.compute() ).toBe( 42 )
            } )
        } )
    }
}

Available after super.setup():

VariableDescription
variables.modelInstantiated model under test
variables.mockLoggerMock LogBox logger
variables.mockLogBoxMock LogBox
variables.mockCacheBoxMock CacheBox
variables.mockWireBoxMock WireBox injector

BaseInterceptorTest — Interceptor Unit

Tests interceptor CFCs in isolation with pre-wired mock helpers. No app load.

class extends="coldbox.system.testing.BaseInterceptorTest"
    interceptor="interceptors.SecurityFirewall"
{
    function beforeAll() {
        super.setup()
    }

    function run() {
        describe( "SecurityFirewall — isolated", () => {
            it( "blocks unauthenticated requests", () => {
                interceptor.preProcess( mockRequestContext, {} )
                expect( mockRequestContext.$once( "noRender" ) ).toBeTrue()
            } )
        } )
    }
}

Available after super.setup():

VariableDescription
variables.interceptorInstantiated interceptor under test
variables.mockControllerMock ColdBox controller
variables.mockRequestServiceMock request service
variables.mockLoggerMock LogBox logger
variables.mockLogBoxMock LogBox
variables.mockFlashMock flash scope

Custom TestBox Matchers (ColdBox adds)

MatcherUsed onDescription
toHaveStatus( code )response objectAssert HTTP status code
toHaveInvalidData( field, msg )response objectAssert cbValidation field violation
toRedirectTo( event )event/request contextAssert relocation target

CommandBox Scaffolding

coldbox create integration-test handler=users actions=index,show,store
coldbox create unit-test name=UserService type=model
coldbox create unit-test name=SecurityFirewall type=interceptor

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,758. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.