MXUnit setup and missing cbController

We have an issue with our test setup and I’m having troubles nailing down which bit we haven’t got quite right yet.

We have an application.cfc in our test directory that extends our regular coldbox app’s application.cfc and we’ve set the wsdl in the MXUnit properties on our project to point to our test directory per the docs. We can even run the unit tests ok. Once. After you run a test once then you can try to run it again and we get this exception:

(500)Element cbController is undefined in a Java object of type class coldfusion.runtime.ApplicationScope.

Oddly enough, if you then go hit one of the coldbox app’s pages in a browser and then try running the unit test again it runs fine. Once. For now we’ve been working around the issue by doing just that - hitting a page in the browser just prior to running each test. Obviously this isn’t ideal if we want to automate our tests.

I’ve traced down the issue to BaseTestCase’s afterTests() function which looks like it removes the coldbox instance from the application scope. In our MyAppBaseTestCase that extends the coldbox BaseTestCase I’ve added in an empty afterTests function that doesn’t call super, and now I can run unit tests repeatedly without having the exception thrown. Still not ideal (feels very much hacky), and you still have to hit the app once before starting to run tests locally. I think this will also still not work well with an automated testing setup.

When I restart the ColdFusion server and then try to run the tests without hitting any pages (which would do all of the onApplicationStart stuff) I get a server 500 error w/o any more specific info from MXUnit in CFBuilder. The details say to hit the WSDL&method=ping in a browser, which I do and it looks like that is (due to our test application.cfc extending our app’s application.cfc) running into issues where the session scope doesn’t exist yet. (Do we need to not extend the regular application.cfc?)

Mainly I’m looking for anything to try or any obvious stuff I may have missed (or read in the docs but misunderstood). Any help would be greatly appreciated.


Some additional info:

  • we’re bootstrapping coldbox in our application.cfc

then in onApplicationStart():
<cfset super.onApplicationStart() />

<cfset application.cbBootstrap = CreateObject(“component”, “coldbox.system.Coldbox”).init(COLDBOX_CONFIG_FILE, COLDBOX_APP_ROOT_PATH, COLDBOX_APP_KEY, COLDBOX_APP_MAPPING) />
<cfset application.cbBootstrap.loadColdbox() />

When I inspect the application scope after hitting a page I see cbBootstrap and cbController containing Coldbox and Controller instances respectively. In our onRequestStart we check for application.cbBootstrap and create it if it doesn’t exist.

We ran into the same thing. I was thinking about doing something similar, but it was too hacky. In particular, if I change a unit test and re-run it, it won’t be the new one. I prefer being reminded that I need to make the cbController exist over re-running the old test thinking it is the new one.

You can extend from your applications original app.cfc because it will try to load ColdBox and your app as well as the virtual applications. You need to decouple them. Recreate mappings, orm, etc in the test application.cfc only.

Thanks for the quick response. It set me on the right path. For reference for anyone else who runs into the same or similar issues, here’s what I was doing wrong and the changes I made to get it working:

Luis I took your suggestion and had our test application.cfc be just what’s in the CB testing wiki as the simplest sample one rather than having our test one extend our real one. It now is:

We have an intermediate MyAppBaseTestCase that we had extending coldbox.system.testing.BaseTestCase (we really ought to be using the base model test case CB provides, but that’s another ticket :slight_smile: After looking in the model base test case I tried adding

which solved another hurdle.

I tracked down a few well-intentioned lines of code in our base test case that tried to reference application.cbController (in order to get to wirebox) and replaced them with simple CreateObject calls (read: we’re not unit testing our base test case itself, so no need to do IOC there).

Those changes now allow me to run our unit tests without any dependence on our ‘real’ CB application.

Thanks again!