MockBox – Mocking a Super Class – Solution

Yesterday I wrote about mocking a super class method while unit testing with MXUnit. If CFC A extends CFC B, and both have the same method name, how do I mock the super method for its call?

Luis Majano with ColdBox wrote up a Blog Post to address how to accomplish this.

Use my example from my previous post:

<!--- Child Class --->
<cfcomponent name="C" extends="message" output="false">
    <cffunction name="send" access="public" returntype="void" output="false">
        <cfargument name="name" type="string" required="true">
        <cfif name neq "test">
            <cfset super.send(name=arguments.name)>
        </cfif>
    </cffunction>
</cfcomponent>

<!--- Parent Class --->
<cfcomponent name="P" output="false">
    <cffunction name="send" access="public" returntype="void" output="false">
        <cfargument name="name" type="string" required="true">
        <!--- Do something --->
    </cffunction>
</cfcomponent>

The super scope is a reference in the variables scope. You can create a MockBox stub to accomplish mocking the super scope. This example creates an empty stub object that mocks the parent send method. The child’s super variable is then overwritten with this stub object. Stub objects are generally used to start working on a project where you are relying on other teams to build that object but has yet to be built.

function setup(){
    variables.mockBox = new mockbox.MockBox();
    variables.component = variables.mockBox.prepareMock( createObject("component","C") );
}

function testSend() {
    // create a virtual super scope and mock a send method on it
    mockSuper = variables.mockBox.createStub().$("send");

    // inject the mock super into the variables scope
    variables.component.$property("super","variables", mockSuper);

    // run the method call
    variables.component.super.$('send');</pre>
}

Luis also states that you can also create a mock of the parent class to leave the methods intact.

variables.mockBox.createMock("P").$("send");

I am still looking for opinions on if I should actually be doing this? Perhaps I should just consider the parent class as a whole and just let the parent method run. What are your ideas on this? How have you handled this in the past and how was your outcome?

#mockbox, #super-class

MockBox – Mocking a Super Class

I’m getting my hands dirty using MXUnit Testing w/ MockBox recently. The basics where fairly easy to pickup, but I’ve now hit a road block. Lets say I need to test this method:

<cfcomponent extends="message" output="false">
    <cffunction name="send" access="public" returntype="void" output="false">
        <cfargument name="name" type="string" required="true">
        <cfif name neq "test">
            <cfset super.send(name=arguments.name)>
        </cfif>
    </cffunction>
</cfcomponent>

So following unit test ideology, I should just test what’s happening in this method and not attached methods.  If I had instantiated an object or the method was in the some component I could just mock the method being called. However since the method is located in the component’s parent, this does not appear to be working. The test contains:

variables.mockBox = new mockbox.MockBox();
variables.component = CreateObject('component', 'thisComponent');
variables.mockBox.prepareMock(variables.component);
variables.component.super.$('send');

This returns the error: “Expression: Element COMPONENT.SUPER is undefined in a Java object of type class [Ljava.lang.String; referenced as ””.

Now technically I could wrap the super.send call inside another local method and mock that method. However that would be coding for the test and would be worthless code and processor usage outside the test.

I’ve Googled this and searched ColdBox’s site for a solution to this, however I’m not getting anywhere.

Does anyone have any ideas or suggestions?

Impressive WP.com Stats

In Feb 2007 WP.com (WordPress) blogged they where running:

  • 152 Physical Processors
  • 511 GB of RAM
  • 174 Hard Drives
  • Several Tera-bytes of Storage

Now 4 years later they are at:

  • 2,475 Physical Processors w/ 8,291 CPU Cores
  • 8,200 GB of RAM
  • 1.3 TB RAM Drives
  • 1.3 Peta-bytes of Storage
  • 8.9 TB of Solid State Disks
  • Plus Amazon S3 as a Backup

So here’s my two cents to add to the load: That’s pretty impressive numbers for a blogging service.

Word 2010 and Pasting Images Fail

I have a Word 2010 document that is pre-populated as a template for writing specifications. It’s nicely laid out with headers, footers, and numbering for sections and sub-sections.

However I can’t get a screen shot to paste correctly for the life of me. I tried using Jing, Alt-Print Screen, and copying from Paint.

Here’s how I can get it to show up:

  • Create a new document and paste
  • Randomly select different parts of the document and the image might show up on random parts of the document either full length or cut off the page.
  • Save the image and insert it into the document using Insert > Picture

None of the above will help me though.

Here’s what I tried, but will not work:

  • Switch to a different document view
  • Try every type of Text Wrap
  • Made sure the placeholder option was disabled
  • Bring Forward, Send Backward
  • Align to Page, Align to Margin
  • … and much more

I know it’s on the page “somewhere” because if I open the “Selection and Visibility” view it’s there and I can format the “invisible picture”. If I give the image a “Picture Layout” I can sometimes see the image being formated.

I searched and searched Google. Turned off smart pasting. Now I’m giving up and saving the image to insert it that way.

If you’ve run into this before, I would love to hear your suggestions as this is a huge time waster! Thanks in advance.

Your Ring Tone Could Kill You

Today in the local news there was a headline “Ring Tone Triggered Dog’s Attack, Owner Says”.

Say what?

Apparently this dog has never shown any signs of aggression before. (lost count how many times I’ve heard this before)

The owner’s friend’s cell phone rang, which mimic’s a dog in distress. Thus the dog thought something was wrong and attacked the source.

So moral of the story, unless you don’t like parts of your body intact, don’t set animal sounds as your ring tone that might prompt attack!

The city voted, and let the owner keep the dog due to the circumstances. Which for the record if you name your dog “Tank” I’m not so sure it’s the sweetest dog in the world.
http://www.ketv.com/news/27024435/detail.html

ColdFusion 9 Query of Query In CFScript

When doing a Query of Query using tag context you see:

<cfquery name="local.myQuery" dbtype="query">
SELECT *
FROM [local].myOtherQuery
WHERE Col1 = 'Chris'
</cfquery>

You would expect you could just do the same in CFScript under ColdFusion 9:

local.queryService = new query();
local.queryService.setName("myQuery");
local.queryService.setDBType("query");
local.objQueryResult = local.queryService.execute(sql="SELECT [Value] FROM [local].myOtherQuery WHERE Col1='Chris'");
local.queryResult= local.objQueryResult.getResult();

However this will produce an error:
coldfusion.sql.imq.imqException: Query Of Queries runtime error.
Table named local.myOtherQuery was not found in memory. The name is misspelled or the table is not defined.

Thanks to Jared Rypka-Hauer, I found a resolution to this lame error by using the setAttributes method:

local.queryService = new query();
local.queryService.setName("myQuery");
local.queryService.setDBType("query");
local.queryService.setAttributes(sourceQuery=local.myOtherQuery);
local.objQueryResult = local.queryService.execute(sql="SELECT [Value] FROM sourceQuery WHERE Col1='Chris'");
local.queryResult = local.objQueryResult.getResult();

This must be done because local.myOtherQuery is out of context at least until they release closures for ColdFusion.

If you would like to see the inner-works of this visit:
\CustomTags\com\adobe\coldfusion\query.cfc in your ColdFusion 9 install directory.

Update 7/7/2011:
Here’s an excellent blog from Ben Nadel also describing a solution to this issue:
http://www.bennadel.com/blog/2224-Performing-Query-Of-Queries-Using-ColdFusion-9-s-Query-cfc-Component.htm

Sending a Variable Dump in Cfscript Mail for ColdFusion 9

Recently I had an issue with a variable that I needed to take a look into. Many times I just mail myself a Cfdump of the variable. Today I tried it completely Cfscript-wise and failed with a “Method writeDump with 1 arguments is not in class coldfusion.runtime.CFComponent.” error. This is what I tried:

local.testVar = 'test';

local.mailerService = new mail();
local.mailerService.setTo('bogus@domain.xyz');
local.mailerService.setFrom('bogus@domain.xyz');
local.mailerService.setSubject('Heres your var dump');
local.mailerService.setType('html');
local.mailerService.send(body=writeDump(local.testVar));

I even tried writing it to a variable (assuming this would fail):

local.testVar = 'test';
local.testDump = writeDump(local.testVar);

local.mailerService = new mail();
local.mailerService.setTo('bogus@domain.xyz');
local.mailerService.setFrom('bogus@domain.xyz');
local.mailerService.setSubject('Heres your var dump');
local.mailerService.setType('html');
local.mailerService.send(body=local.testDump);

But that just failed with the same error on the second line above.

I really couldn’t find anything on this in Google, but after manipulating my keywords for awhile, I ran across a blog with a code sample that seems to accomplish what I needed. The key was to run “savecontent” as save the contents off into a variable:

local.testVar = 'test';
savecontent variable="local.testDump" {
writeDump(local.testVar)
}

local.mailerService = new mail();
local.mailerService.setTo('bogus@domain.xyz');
local.mailerService.setFrom('bogus@domain.xyz');
local.mailerService.setSubject('Heres your var dump');
local.mailerService.setType('html');
local.mailerService.send(body=local.testDump);

Now before you say why would I dump a string, I was actually trying to dump a query result.

On a side-note, feel free to come to the Nebraska ColdFusion Users Group tonight and learn neat things like this!

Query Of Queries syntax error. Encountered “local.

If you’ve encountered an error “Query Of Queries syntax error. Encountered “local.” while running a Query of a Query in ColdFusion, thanks to Ben Nadel I have the solution.

<cfquery name="local.myQuery" dbtype="query">
SELECT [value]
FROM local.myQueryResults
WHERE [name] = 'Chris'
</cfquery>

Running the above code will error out due to “local” being a reserved keyword in SQL. The solution is to wrap “local” in brackets like “[local]”.

<cfquery name="local.myQuery" dbtype="query">
SELECT [value]
FROM [local].myQueryResults
WHERE [name] = 'Chris'
</cfquery>

SQL VARCHAR(MAX): The New TEXT

Normally, if I’ve ever needed a large amount of text data stored in a database field, I would use a column type of text. I would usually do this when going beyond 256 characters. I think this stems back to use MS SQL 6.

Now as of SQL 7, the varchar type can hold around 8000 characters (8k) and nvarchar can hold around 4000 characters. This limitation stems from the 8KB internal page size SQL Server uses to save data to disk. But who really wants to deal with putting in client-side validation of 8k characters when you can just make it unlimited?

But the pain from using the type text comes in when trying to query against it. For example grouping by a text type is not possible.

Another downside to using text types is increased disk IO due to the fact each record now points to a blob (or file).

Most clients that I’ve worked on are still on SQL 2000, and maybe 2005 – so I haven’t really caught up to the nifty 2005 and 2008 changes yet. Reason? MS SQL Servers are freak’n expensive!

In SQL Server 2005 Microsoft added support for the varchar(max) and nvarchar(max) data types. The difference between varchar(8000) and varchar(max) is that it can now store up to 2GB of data (about 2,147,483,647 characters) instead of 8K. That seems to be plenty in my books for anything I need it for. Continue reading

Returning IDENTITY ID via ColdFusion 9’s CFQuery

Many of us are familiar with using:

SELECT @@IDENTITY AS ID

or in later versions of MSSQL:

SELECT SCOPE_IDENTITY() AS ID

in your SQL statement to return the last identity value that you just inserted into a SQL Table.

In ColdFusion 8 you could also use:

<cfquery datasource="#DSN#" result="myResult">
INSERT INTO MyTable (col1)
VALUES ('col1')
</cfquery>

<cfoutput>Inserted ID is: #myResult["IDENTITYCOL"]#</cfoutput>

(Use: IDENTITYCOL for SQL Server, ROWID for Oracle (is rowid not primary key), SYB_IDENTITY for Sybase, SERIAL_COL for Informix, GENERATED_KEY for MySQL)

However in ColdFusion 9 they standardized the variable name to GENERATEDKEY for all SQL environments.

<cfquery datasource="#DSN#" result="myResult">
INSERT INTO MyTable (col1)
VALUES ('col1')
</cfquery>

<!--- Tag based output --->
<cfoutput>Inserted ID is: #myResult["GENERATEDKEY"]#</cfoutput>
<!--- Script based output --->
insertedID = myResult.getPrefix().generatedkey