[ColdBox 3.7.0] Change Datasource for UnitTesting with MXUnit

Hi Everybody,

I have managed to run UnitTesting for my Project an need your tips to do it better.
I need to change datasource for Testing, because i would like to add DBUnit to UnitTesting and also for other reason.

So how can i override for UnitTesting only this part of a Modulconfig.

datasources = { myDSN = {name="DSN_db_live",dbtype="mssql"} };

Or how can i generally override Modulconfig for Testing.

regards
Raja

The easiest would be to mock the DB calls to begin with, but if you need to test them I would look into wrapping them in a transaction block and roll the data back at the end of the test. I have never tried this solution, but you could switch the manage persistent to be managed by you and not flush the session as well.

Transactions do undo work, but they don’t redirect work. It is not atypical to have a development/test datasource, allowing your production sources to stay secure, housed, and only having production loads. Knowing how to modify the datasource easily is a good idea, and I would like to know how to best do that as well; we are moving in that direction, too.

Why would you be unit testing production code?

And what do you mean by redirect work?

Let me elaborate a bit what i’m trying to achieve. We got more or less 4 Stages/Systems for an application.

0] Unittesting on Dev Machine: db_unit
1] Dev Machine on which i develop the code, where the DB gets the inputs as i manually test: db_dev

What I mean by redirect work is that transactions can be used to rollback and commit, but they don’t have a switch for making queries be performed on one or another server. During testing, one would generally avoid running test queries against production databases, hence the need to redirect the query, causing the work to be run by something non-production.

Does that make sense?

I wouldn’t test all queries of my source code, but I can see myself wanting to test some of the more complex queries.

Michael, it sounds like the process your using is complicated and wrong. When I asked what I asked, it was to determine how your setup is for testing. Development should be close to production as far as settings go, but production should never have tests being run on it.

So my next question, is why are you using Unit Tests on any other server other than your development servers and development database.

You can mock anything you so desire, when it comes to databases one should be looking at mocking them for anything code related, for all your models and handlers. So that the database is never modified in the end.

So if you where to be doing Unit Testing the right way, you would start with creating your test handler and make it fail first, you would then modify the UnitTest to test what you expect from an input and output situation. You then right your handler to do what you need it to do, in this case you would mock the database call because you are only interested in getting the handler to run without failing.

Any time you need to then go outside of the handler, you need to start to unit test those calls as well. With ORM and databases you would typically Mock these to then satisfy the needs of having that handler run without errors. Because database are constant factors you ask for what you want you get what you want, it makes perfect sense to mock all databases interaction with any handler or model or service that you are testing.

However that is the ideal world with Unit Testing, in most peoples cases, they tend to write the code and then unit test and find themselves getting lost very quickly.

Hopefully that helps, but you should not be reliant on any data in the database to run. If you do then anything that is required to satisfy the unit test, when it comes to data from the database is to mock these.

Hi everybody

I finally solved it like this. I have removed the datasources entry in all ModuleConfig since I’m not using different Database for each module and add the following to Coldbox.cfc

if(REFind("^.*\/test.*", cgi.script_name) GTE 1) { datasources = { myDSN = {name="DSN_unittest",dbtype="mssql"} }; }else { datasources = { myDSN = {name="DSN",dbtype="mssql"} }; }

Because Unittesting is always done in the folder called test this should work. Any opinion on this approach is appreciated.

lol, look at the development settings and you will see you don’t need to do it like that.

For example you could do it like this

https://www.andyscott.id.au/blog/setting-up-your-coldbox-30-application-for-development-and-production

or you could do it like this in your coldbox config

// environment settings, create a detectEnvironment() method to detect it yourself.
// create a function with the name of the environment so it can be executed if that environment is detected
// the value of the environment is a list of regex patterns to match the cgi.http_host.
environments = {
development = “^127.0.0.1”
};

and then it will call this…

// ORTUS DEVELOPMENT ENVIRONMENT, REMOVE FOR YOUR APP IF NEEDED
function development(){

coldbox.debugmode=true;

//Debugger Settings

settings.productionMode = false;

// debugging file
logbox.appenders.files={class=“coldbox.system.logging.appenders.AsyncRollingFileAppender”,
properties = {
filename = “ContentBox”, filePath="…/logs"
}
};

logbox.debug = [“coldbox.system.interceptors.Security”];
logbox.debug = [ “coldbox.system.aop” ];
logbox.debug = [“root”];

}

Jep thats a solution i have checked first. But that won’t work, since i’m developing and unittesting on the same machine and “the value of the environment is a list of regex patterns to match the cgi.http_host”. In my case the cgi.http_host has no difference.

With my solution i do more or less the same - it could be more sophisticated i know.