Mocking EntityLoad?

28 views
Skip to first unread message

Jonathan Price

unread,
Jun 19, 2015, 3:40:47 PM6/19/15
to mxu...@googlegroups.com
I have a simple service function that does something like this:

    public array function getArray( string documentType = '', string documentIDs = '', numeric maxRows = 20 ) {
        
        local.returnArray = ArrayNew(1);

        local.q_docs = variables.documentDb.get(
            documentType = arguments.documentType, documentIDs = arguments.documentIDs, maxRows = arguments.maxRows );

        if (local.q_docs.RecordCount NEQ 0) {
            for ( intRow = 1 ;  intRow LTE local.q_docs.RecordCount;  intRow = (intRow + 1) ) {
                local.document = EntityLoad("Document", local.q_docs[ "DocumentID" ][ intRow ], true);
                ArrayAppend(local.returnArray, local.document);
            }
        }

        return local.returnArray;
    }

Basically - the .get() function returns a query which is then iterated over to build an array of object for return.  I'd LIKE to test this function in isolation, without the actual need of a DB.   Mocking the query return for the .get() call is easy enough, but I'm not really sure how to handle the EntityLoad line.  Any suggestions?

ALLISON John

unread,
Jun 21, 2015, 6:38:37 PM6/21/15
to mxu...@googlegroups.com
Jonathan,

I'm reasonably new to this so take this with a grain of salt, but here's how I handle this:

You need to avoid ORM functions like entityLoad/entityNew/etc in your testable functions.
This means you need to abstract them into service objects. Then you can stub out the service objects in your tests in the same way you're stubbing DocumentDB.

e.g:
<cfcomponent displayname=”DocumentDAO” output=”no”>
<cffunction name=”loadDocument” returntype=”Document” output=”no”>
<cfargument name=”documentId” type=”numeric” required=”yes” />
<cfreturn entityLoad(“Document”, arguments.documentId, true) />
</cffunction>
</cfcomponent>

And your code:
<!--- snip --->
for ( intRow = 1 ;  intRow LTE local.q_docs.RecordCount;  intRow = (intRow + 1) ) {
local.document = variables.DocumentDAO.loadDocument(local.q_docs[ "DocumentID" ][ intRow ]);
ArrayAppend(local.returnArray, local.document);
}
<!--- snip --->

I take it further and run my tests using a runner in a subfolder with its own Application.cfc which does not have ORM enabled. This means any calls to ORM functions will throw errors - the idea is to completely isolate your unit tests from real DB interaction.

John.
--
You received this message because you are subscribed to the Google Groups "mxunit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mxunit+un...@googlegroups.com.
To post to this group, send email to mxu...@googlegroups.com.
Visit this group at http://groups.google.com/group/mxunit.
For more options, visit https://groups.google.com/d/optout.

--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.

Puritan Paul

unread,
Jun 21, 2015, 11:12:44 PM6/21/15
to mxu...@googlegroups.com
It's funny - that's exactly what I did yesterday. I like the idea of a runner app with Orm disabled too! Thanks for the help.

Puritan Paul

unread,
Jun 21, 2015, 11:16:02 PM6/21/15
to mxu...@googlegroups.com
Sorry - but can you tell me what you're returning from your DAO mock if ORM is disabled in the runner? I left it enabled and had the mock return the object that I entityloaded from within the test. I'm curious to know how you handled that if you have to a second. This is all pretty new for me, too.



> On Jun 21, 2015, at 3:37 PM, ALLISON John <j.al...@ed.ac.uk> wrote:
>

ALLISON John

unread,
Jun 22, 2015, 5:00:19 AM6/22/15
to mxu...@googlegroups.com
You can simply create your "ORM" object using 'new' or 'createObject'. Populate it as required by your test using its setters. It will still work as a 'dumb bean' if ORM is not enabled, the attributes like 'entityName' and 'table' are just ignored.

John.

--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.

Reply all
Reply to author
Forward
0 new messages