What is the best way for unit test cfc that uses a Java object to perform many functions?

I have cfc that relies heavily on a Java object (created using JavaLoader) for many of its core functions that I would like to write for some tests, and I'm not sure if the best way to do this is Here's an example of a method that I would like to write for a test with an instance of instance.note, which is a java object.

<cffunction name="getNotes" returntype="Array" access="public" output="false" hint="I return a list of a users notebooks" > <cfargument name="maxCount" type="numeric" required="false" default="9999" hint="The maximum number of notes to get" /> <cfscript> if(arguments.maxCount) return instance.note.listNotes(maxCount); else return instance.note.listNotes(); </cfscript> </cffunction> 

One thing I was thinking of doing was to create a CFC stub that has the same method names and similar return values, and then mock that stub and inject it?

+4
source share
3 answers

When we needed unit test CF functions that relied on Java objects (which we did LOT), we used Mockito to mock Java objects.

So, hoping this piece of code makes sense, it has been almost a year since I did this:

 <cfcomponent displayname="TestWhatever" extends="mxunit.framework.TestCase" output="false"> <cffunction name="setUp" access="public" returntype="void"> <cfscript> // named it mk for keeping it short variables.mk = createObject("java","org.mockito.Mockito"); //Create the mock object variables.mockNote = mk.mock(createObject("java","com.company.whatever.note").getClass()); // Mock Data fullList = {whatever listNotes() returns} partialList3 = {whatever listNotes(3) returns} //some common mocking mk.when(variables.mockNote.listNotes()).thenReturn(fullList); mk.when(variables.mockNote.listNotes(mk.eq(3))).thenReturn(partialList3); mk.when(variables.rootOrgObj.guid()).thenReturn("root"); // Assign the mock object to where your CFC expects it. instance.note = variables.mockNote </cfscript> </cffunction> </cfcomponent> 

Having said that, if your fetch function is real, there really is no point in testing it in a module. It just does nothing but a proxy for the Java object. There is no significant logic for testing.

Since you have a default value for cfargument, it will always exist (again, I think it has been a year since I did CF), so your guard instructor is not even required - the first code path will always be called with the passed maxCount if specified, or from 9999 if not.

+2
source

Can you just write meaningful statements about the result, i.e. about an array of notes? Looking at this code, the only thing I checked: a) when you pass maxCount, does your resulting array honor this size? b) without maxCount - a list of notes that you expect? Because it does all your code. I would check your code, not the code of the underlying java object.

+3
source

I took Edward and implemented it like this:

I used the JavaLoader library to create my mockito object. variables.cfEvernote = "";

 variables.classLoader = createObject("component", "resources.JavaLoader"). init(["#expandPath('../lib/mockito-all-1.8.5.jar')#", "#expandPath('../lib/CFEvernote.jar')#", "#expandPath('../lib/libthrift.jar')#", "#expandPath('../lib/evernote-api-1.18.jar')#"]); variables.mockito = variables.classLoader.create("org.mockito.Mockito").init(); 

Then, in the installation method of my munit test, I create my new mock java object:

 <cffunction name="setUp" access="public" output="false" returntype="void"> <cfscript> variables.cfEvernote = createObject("component","com.714studios.cfevernote.CFEvernote"). Init(variables.configArray[1],variables.configArray[2], "sandbox.evernote.com", "http://localhost/cfevernote/callback.cfm" "#ExpandPath('../lib')#"); variables.mockCFEvernote = variables.mockito.mock(variables.classLoader.create("com.sudios714.cfevernote.CFEvernote"). Init("123","S1","232","sandbox.evernote.com","mock").getClass()); variables.cfEvernote.setCFEvernote(mockCFEvernote); </cfscript> 

Then in my tests I create my mock behavior like this.

 <cffunction name="test..." returntype="void" access="public" output="false" > <cfscript> var notebooks = ""; var expected = 12; var i = 0; var retArray = createObject("Java","java.util.ArrayList"); var actual = ""; for(i = 1; i lte 12; i = i + 1){ retArray.Add(""); } variables.mockito.when(mockCFEvernote.listNotebooks(12)).thenReturn(retArray); notebooks = variables.cfEvernote.getNotebooks(12); actual = arrayLen(notebooks); assertEquals(expected,actual); </cfscript> 

I also talked about this in more detail here - http://blog.bittersweetryan.com/2011/07/unit-testing-coldfusion-components-that.html .

0
source

All Articles