Unit Testing with CB, MXUnit, and Eclipse

Hi folks,

Hope you've all recovered from holiday festivities! Over the break I decided to get more familiar with using MXUnit with CB. I've managed to get ColdBox and Eclipse configured to read my tests directory, however with I run the tests inside Eclipse I receive the following MXUnit exception

XMLApplicationLoader.ConfigXMLFileNotFoundException: The Config File: /Library/WebServer/Documents/myapp/config/coldbox.xml.cfm can't be found.
  at /Library/WebServer/Documents/frameworks/coldbox/system/core/util/Util.cfc: 149
  at /Library/WebServer/Documents/frameworks/coldbox/system/web/loader/XMLApplicationLoader.cfc: 59
  at /Library/WebServer/Documents/frameworks/coldbox/system/web/services/LoaderService.cfc: 52
  at /Library/WebServer/Documents/frameworks/coldbox/system/testing/BaseTestCase.cfc: 119
  at /Library/WebServer/Documents/guardly-platform/api/v01/test/integration/AppleTest.cfc: 6

I'm using one of the nightly builds from a couple of weeks ago which is using Coldbox.cfc for config as opposed to coldbox.xml.cfm

Any idea's what up with this? I'm looking forward to (finally) getting unit testing working with my app.

Greatly appreciated.

Thanks.

Nolan

Can you post your test

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Hi Luis,

This is one of my test files, which I auto-generated when I created the handler. I haven’t written any code other than what was generated by CB Utilities.

Thanks.

Nolan

component extends=“coldbox.system.testing.BaseTestCase” appMapping="/"{

/**

  • You can remove this setup method if you do not have anything to setup
    */
    void function setup(){
    //Call the super setup method to setup the app.
    super.setup();

// Your own setup here if needed
}

function testgetContact(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.getContact”);

//Do your asserts below

}

function testcreateContact(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.createContact”);

//Do your asserts below

}

function testupdateContact(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.updateContact”);

//Do your asserts below

}

function testremoveContact(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.removeContact”);

//Do your asserts below

}

function testgetUserContacts(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.getUserContacts”);

//Do your asserts below

}

function testlistContacts(){
var event = “”;

//Place any variables on the form or URL scope to test the handler.
//URL.name = “luis”

// Execute Event
event = execute(“Contact.listContacts”);

//Do your asserts below

}

}

Hi folks,

So I did a little digging and I was able to get rid of the below error by commenting out the setUp function in my Test file.

Can anyone describe how the setup function would be used? I would assume that at some point I might need to use this function so it appears that there might be an issue given the error below.

After commenting out setUp and re-running the tests I now receive the following error:

Object: The getSetting method was not found. Either there are no methods with the specified method name and argument types or the getSetting method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

Again, i’m really new at unit testing with CB so i’m sort of stumbling along…

Here is what my test function looks like, which is throwing this error:

var event = "";

// Execute the event
//test placing a userid in the request collection
rc.userid=1;
event = execute(“User.getUser”);

//Do your asserts below

Another question comes to mind… If I have route patterns defined in my app in addition to handler method security, is there a specific way I should be constructing my tests in order to support those conifgurations?

Thanks again.

Nolan

I don’t believe you need to do anything special–other than making sure your variables are loaded with the values you are looking for. For example, in your integration test, you can make sure SESSION.CanAccessMySite is TRUE (or what ever your requirements are).

Integration testing is trying to mimic a request as close to possible, so, just provide the cookie, session, client (or other) variables you need before you execute your handler under test.

Thanks,

Aaron Greenlee
http://aarongreenlee.com/

Thanks for your email Aaron.

So when MXUnit runs against the generated test handlers are the tests being performed in isolation against the handlers, or would interceptors such as Security.cfc also being executing prior to the handler test being run? Just wondering as knowing this will dictate how my tests should be setup? I’ve seen some dialogue on other threads where other developers will setup unique sets of tests for models, plugins, interceptors, etc. Wondering if the group can provide some examples and best practices how to best setup tests for apps?

Regarding my previous error I dug a little deeper and it appears the error is happing on line 304 of BaseTestCase.cfc

// Setup the incoming event URL[getController().getSetting("EventName")] = arguments.event; //this is line 304 // Capture the request getController().getRequestService().requestCapture();

This is the error which is produced in MXUnit:

Object: The getSetting method was not found. Either there are no methods with the specified method name and argument types or the getSetting method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

Any ideas?

Thanks.

Nolan

Integration tests are not performed in isolation–except of course your layouts/views will not be rendered. This is almost like simulating a browser request. For example, you may simulate a user login by adding variables to the FORM scope before executing your handler.

ColdBox 3 executes the following when doing an integration test:

  • Execute ApplicationStartHandler

  • Execute preProcess interceptors

  • Execute RequestStartHandler

  • Execute event in testing

  • Execute RequestEndHandler

  • Execute postProcess interceptors

If you are not doing anything in your setup method, you can omit it. ColdBox will execute it for you implicitly as long as you are extending “coldbox.system.testing.BaseTestCase”.

If you do not specify ‘configMapping=foo/bar/ColdBox.cfc’ in your component declaration, ColdBox will look for your Configuration CFC in the following location: {appmapping}/config/ColdBox.cfc.

In my applications, I always setup an application mapping called ‘app’ which refers to my application’s root. In my test application.cfc, I make sure ‘app’ points to the main application and not my testing application. I started doing this to help me share code between applications (interceptors, models, etc…) and I have a feeling my tests have always benefited from that.

You may want to verify your app mapping of ‘/’ is pointing to the right place as it will impact your configMapping.

-Aaron Greenlee
http://aarongreenlee.com/

Also, if you are running from the MXUnit Test Runner, you will want to explicitly define your RemoteFacade URL for the project. This also may be a cause.

Aaron Greenlee
http://aarongreenlee.com/

Hi Aaron,

thanks for the clarification on the execution stack. I made a change to my appMapping and I was able to get past the first error.

Question, does the Application.cfc which resides in the “test” folder need to extend Coldbox?
The app I am testing against also uses ORM both CB’s ORMService and ACF9 implementation. I seem to remember a thread which indicated that ORM settings need to be added to the “test” application.cfc in order for tests to work (if the application being tested uses ORM). Correct?

Regardless, when I run a simple test I now get the following error:

coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.AbortException : null]

This doesn’t tell me much. :frowning: Is there any way I can dig deeper to find out why this error is occurring?

My test function looks like this:

var event = "";

//Place any variables on the form or URL scope to test the handler.
form.firstName = “Jimmy”;
form.lastName = “Jamerson”;
form.email = “jimmyjames@rickrichards.com”;
form.mobileTelephone = “4165551212”;
form.eulaAccepted = true;
// Execute the event
event = execute(“User.createUser”);

//Do your asserts below

Thanks all. Greatly Appreciated.

Nolan

Nolan,

See if this helps you.

http://blog.coldbox.org/post.cfm/unit-testing-with-coldbox-mxunit-and-cf9-orm

Curt

Hi Curt,

Thanks for the link. This is exactly how I configured the ORM settings for my test folder application.cfc. Good to have the link as a reference now.

I still get the same error when performing a test:

coldfusion.xml.rpc.CFCInvocationException: [coldfusion.runtime.AbortException : null]

Any other ideas?

Cheers.

Nolan

Can you attach the full stack trace?

Curt

I'm running the test using the MXUnit eclipse plugin, and that's all that is printed to the output panel.

I'm running CF via cmd line and this is what outputs to terminal:

12/29 15:17:45 Information [jrpp-892] - Initialized TestRun with key 05CA8641-C9A0-8C13-74EE22B586CAEF1D
12/29 15:17:45 Information [jrpp-892] - Initializing cache with key 05CA8641-C9A0-8C13-74EE22B586CAEF1D
INFO coldbox.system.testing.mock.web.MockController ColdBox Application Controller Created Successfully at /Library/WebServer/Documents/guardly-platform/api/v01/ ExtraInfo:
12/29 15:17:46 Information [jrpp-898] - RemoteSuiteCount: initial 1; now: 0

Thoughts?

Thanks.

Nolan

Hi guys,

Just wondering if anyone has anymore thoughts on this. I've hit a roadblock on this and haven't been able to resolve.

Happy New Year everyone.

Cheers,

Nolan

I think you’ll need to share your project for any more help. Can you share the relevant parts?

I could send a few files.

What would be best to debug?

Cb config file
Handler
Unit test file for handler
Interceptors

I’m trying to narrow it down to the minimum. Could I also try running the test from the mxunit web UI to see if more detailed errors are produced?

Thanks.

Nolan.

Load .,8,1

When tests are driving me crazy, I often will add dumpAborts and debug via the Web interface.

Often, I also add writeDump(var=fooBar,output=‘c:\debug.log’); and watch my debugs with ColdFusion Builder’s TailView.

The more code you share the better. You can email me personally if you would like, Nolan.

Thanks.

-Aaron Greenlee
http://aarongreenlee.com/

Or you could just use the ColdFusion Builder debugger, much better to see what’s going on.

Regards,

Andrew Scott

http://www.andyscott.id.au/

The debugger is too slow for me. And, I’ve got a super amazing ultra fast computer :frowning:

Thanks guys.

I’m going to give both a shot and if I still can’t get past the error I’ll send you a note offline Aaron. Cheers.

Nolan