agentsclimarketplace

Testing model

Skill ColdBox/skills/coldbox/testing-model

Collection of skills for the ColdBox Platform and Claude Plugin

Install
npx -y skills add ColdBox/skills --skill testing-model

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.

What its author says it does

Copied from the file, not written here

Use this skill when unit testing ColdBox model objects (services, repositories, entities, or utility classes) in isolation using BaseModelTest, accessing the pre-wired model variable, leveraging the built-in mock helpers (mockLogger, mockLogBox, mockCacheBox, mockWireBox), calling model.init() to initialize the component, mocking injected properties with prepareMock(), or scaffolding model tests with CommandBox.

SKILL.md

7.4 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

Model / Service Unit Testing in ColdBox

When to Use This Skill

  • Unit testing a service, repository, ORM entity, or utility model in complete isolation
  • Mocking logger, LogBox, CacheBox, or WireBox dependencies pre-wired by ColdBox
  • Testing model logic without loading the full ColdBox virtual app
  • Injecting MockBox stubs for model's injected properties

Base Class

coldbox.system.testing.BaseModelTest

Extends BaseTestCase with loadColdBox="false" — no virtual app is started. Your model CFC is instantiated and handed to you in variables.model.


Minimal Setup

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

    function beforeAll() {
        super.setup()          // creates variables.model and pre-wired mocks
        model.init()           // call your component's own init() if needed
    }

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

            it( "returns an empty array by default", () => {
                expect( model.findAll() ).toBeArray()
            } )

        } )
    }
}

Pre-Wired Mock Variables

After calling super.setup(), the following MockBox-created stubs are available:

VariableTypeDescription
variables.modelCFC instanceThe model under test
variables.mockLoggerMock objectStand-in for LogBox.getLogger()
variables.mockLogBoxMock objectStand-in for the full LogBox instance
variables.mockCacheBoxMock objectStand-in for CacheBox
variables.mockWireBoxMock objectStand-in for the WireBox injector

Inject these into your model when its properties reference them:

function beforeAll() {
    super.setup()

    // inject mock logger if UserService has property name="log" inject="logbox:logger:{this}"
    prepareMock( model )
        .$property( propertyName = "log", mock = mockLogger )
        .$property( propertyName = "wirebox", mock = mockWireBox )

    model.init()
}

Mocking Collaborating Services

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

    function beforeAll() {
        super.setup()

        variables.mockProductRepo = createMock( "models.ProductRepository" )
        variables.mockEmailer     = createMock( "models.MailService" )

        prepareMock( model )
            .$property( propertyName = "productRepository", mock = mockProductRepo )
            .$property( propertyName = "mailService",       mock = mockEmailer )

        model.init()
    }

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

            it( "places an order and sends a confirmation email", () => {
                mockProductRepo
                    .$( "findById" )
                    .$results( { id: 1, price: 29.99, stock: 10 } )

                mockEmailer.$( "send" ).$results( true )

                var order = model.placeOrder( productId = 1, quantity = 2, userId = 42 )

                expect( order.status ).toBe( "confirmed" )
                expect( mockEmailer.$once( "send" ) ).toBeTrue()
            } )

            it( "throws when stock is insufficient", () => {
                mockProductRepo
                    .$( "findById" )
                    .$results( { id: 1, price: 29.99, stock: 0 } )

                expect( () => {
                    model.placeOrder( productId = 1, quantity = 5, userId = 42 )
                } ).toThrow( type = "models.OrderService.InsufficientStockException" )
            } )

        } )
    }
}

init() Patterns

Some models accept constructor arguments; others use WireBox property injection only. Match the pattern your model uses:

// Pattern 1: no-arg init (injection-only model)
model.init()

// Pattern 2: init with arguments
model.init( dsn = "myDB", timeout = 30 )

// Pattern 3: no init needed (properties all mock-injected before any usage)
prepareMock( model )
    .$property( propertyName = "userGateway", mock = mockGateway )
// call model methods directly without init()

Testing Model with ORM Entities

When a model interacts with ORM:

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

    function beforeAll() {
        super.setup()

        variables.mockORM = createMock( "cborm.models.BaseORMService" )
        prepareMock( model )
            .$property( propertyName = "postRepository", mock = mockORM )

        model.init()
    }

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

            it( "finds published posts", () => {
                mockORM
                    .$( "findAllWhere" )
                    .$results( [
                        { id: 1, title: "Hello", status: "published" },
                        { id: 2, title: "World", status: "published" }
                    ] )

                var posts = model.getPublished()
                expect( posts ).toHaveLength( 2 )
                expect( mockORM.$once( "findAllWhere" ) ).toBeTrue()
            } )

        } )
    }
}

Testing Private / Protected Methods with MockBox

function run() {
    describe( "UserService private methods", () => {

        it( "hashes passwords correctly", () => {
            prepareMock( model )
            // makePublic exposes private/package methods for testing
            model.$( "hashPassword", "hashed_result" )

            var hash = model.$getProperty( "hashPassword" )
            // alternatively call via invokePrivate if TestBox supports it:
            var result = model.invokePrivate( "hashPassword", [ "mypassword" ] )
            expect( result ).toBe( "hashed_result" )
        } )

    } )
}

Asserting Log Calls

it( "logs an error when save fails", () => {
    mockProductRepo.$( "save" ).$throws( message = "DB Error", type = "DatabaseException" )
    mockLogger.$( "error" )

    expect( () => { model.saveProduct( {} ) } ).toThrow()
    expect( mockLogger.$once( "error" ) ).toBeTrue()
} )

CommandBox Scaffolding

# Generate a model and its unit test together
coldbox create model name=UserService properties="name,email" --tests

# Or generate just the test
coldbox create unit-test name=UserService type=model --open

The generated file extends BaseModelTest with the model annotation pre-filled.


Key Patterns Summary

PatternCode
Extend base classextends="coldbox.system.testing.BaseModelTest" model="models.MyService"
Boot modelsuper.setup() then model.init()
Inject mock loggerprepareMock( model ).$property( propertyName="log", mock=mockLogger )
Mock a collaboratorcreateMock("models.Other"), inject via $property()
Assert method calledexpect( mockX.$once("method") ).toBeTrue()
Stub return valuemockX.$( "method" ).$results( value )
Stub exceptionmockX.$( "method" ).$throws( message, type )

What ships with it

Read from the repository

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

Keep looking

Skills are one crate of 326,970. 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.