Testing ActiveEntity Models and their validation constraints

Hi everyone,

Looking for some guidance as I’m at my wits end after two days trying to get this. I’m writing a BDD test for a model that extends ActiveEntity. I’d like to be using the .isValid() method in my tests just as I would in my application code. I’m testing to make sure the constraints are all there on the model and the correct rules are in place.

Wirebox cannot seem to locate ValdiationManager@cbvalidation when running isValid() from the tests. That function in ActiveEntity.cfc runs var validationManager = application.wirebox.getInstance( “ValidationManager@cbvalidation” );

Here’s what i have ( I stripped some other tests out):
cborm is installed to /modules/cborm and its dependency cbvalidation is in /modules/crborm/modules/cbvalidation – as expected.

/tests/spec/unit/UserTest.cfc:

`

component extends=“coldbox.system.testing.BaseModelTest” model=“models.User”{

function beforeAll(){
// load ColdBox
this.loadColdbox = true;

// setup the model
super.setup();

// init the model object
model.init();;

}

function afterAll(){
this.unloadColdbox = true;
}

function run(){

describe( “models.User Suite”, function(){

beforeEach(function( currentSpec ){
// Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST.
setup();

ormService = getMockBox().createMock( “cborm.models.BaseORMService” );
mockEH = getMockBox().createEmptyMock(“cborm.models.EventHandler”);

});
describe( “property contraints”, function(){
describe( “username”, function(){
it( “should be required”, function(){
user = ormService.new( “User”);
expect( user.isValid() ).toBeFalse();
user.setUsername(‘abcdefghijk’);
expect( user.isValid() ).toBeTrue();
});
});
});
});
}
}

`

/models/User.cfc

`

component entityName=“User” persistent=“true” table=“users” extends=“models.BaseEntity” {

// Primary Key
property name=“id” fieldtype=“id” generator=“uuid”;

// Properties
property name=“userName” ormtype=“string” index=“userName”;

// Validation
this.constraints = {
userName = {
required = true,
min = 6
}
};

// Constructor
User function init() {
return this;
}
}

`

/tests/Application.cfc

`

component{

// APPLICATION CFC PROPERTIES
this.name = “ColdBoxTestingSuite” & hash(getCurrentTemplatePath());
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan( 0, 0, 15, 0 );
this.applicationTimeout = createTimeSpan( 0, 0, 15, 0 );
this.setClientCookies = true;

// Create testing mapping
this.mappings[ “/tests” ] = getDirectoryFromPath( getCurrentTemplatePath() );
// Map back to its root
rootPath = REReplaceNoCase( this.mappings[ “/tests” ], “tests(\|/)”, “” );
this.mappings["/root"] = rootPath;
this.mappings["/app-core"] = “…/”;
this.mappings["/appcore"] = “…/”;
this.mappings[ “/cborm” ] = “…/modules/cborm”;

this.mappings[ “/cbi18n” ] = “…/modules/cborm/modules/cbi18n”;
this.mappings[ “/cbvalidation” ] = “…/modules/cborm/modules/cbvalidation”;

this.datasources[“app_core_test”] = {
class: ‘org.gjt.mm.mysql.Driver’
, connectionString: ‘theConnString’
, username: ‘root’
, password: “mms888”
};
this.ormenabled = true;
this.ormsettings = {
cfclocation = [“models”],
datasource = “app_core_test”,
dbcreate = “dropcreate”,
useDBForMapping = false,
// Active ORM events
eventHandling = true,
dialect = “MySQL5”,
// Use the ColdBox WireBox Handler for events
eventHandler = “cborm.models.EventHandler”,
autoManageSession = false,
logSQL = true
};

// request start
public boolean function onRequestStart(String targetPage){
if ( structKeyExists( url, “reload_orm”) ) {
ormReload();
}

return true;
}

}

`

Everything is in /Application.cfc, /config/Coldbox.cfc, and /config/Wirebox.cfc are pretty much default scaffold from standing up a new app via CommandBox

I’ve tried quite a few different things. I’ve tried mocking ValidationManager but that seemed to be a rabbit hole of mocking it’s dependencies, and it’s dependencies dependencies.

I have looked at cborm’s tests for ActiveEntity::isValid() and tried mocking my User model much the same and didn’t have luck either.

Help is greatly appreciated. Great thanks!

Well, we seemed to have ironed it out. I’m not quite sure WHY this works but it clearly does. Any insight would be appreciated.

in /coldbox/system/testing/BaseModelTest.cfc

We wrapped the mockWirebox in an if for loading Coldbox. We’re using the changes made by Sean Herrala (member on my team) last week that fixed some loading of Coldbox with model tests.

`

if( !this.loadColdBox ) {
variables.mockWireBox = mockBox.createMock( “coldbox.system.ioc.Injector” ).init();
}

`

For some reason, this was interfering with Coldbox loading up Wirebox and losing all the hooks in there that Coldbox had been loaded. We were seeing it using the DefaultBinder.cfc during the tests instead of the regular Binder.cfc

Looking forward to writing more tests - coincidentally, I’ll be making a pull request for cbvalidation soon. There’s a bug with Null:empty properties…But that’s for another thread :wink:

-Dan

The BaseModelTest is used only when you will mock EVERYTHING.You need to use the BaseTestCase and load a virtual ColdBox app

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com
P/F: 1-888-557-8057
Direct: (909) 248-3408

ColdBox Platform: http://www.coldbox.org

ContentBox Platform: http://www.gocontentbox.org
Linked In: http://www.linkedin.com/pub/3/731/483

Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano | twitter.com/gocontentbox