com.sebtools Build 12 Documentation: RecordsTester.cfc

RecordsTester.cfc

The RecordsTester component is meant to make it easier to run tests against Records.cfc components using MXUnit. This isn't to say that MXUnit isn't already easy, but rather to take advantage of features of Records.cfc to make testing as easy as possible.

RecordsTester.cfc extends "mxunit.framework.TestCase" (so MXUnit is required in order to use it). The "setUp" method in RecordsTester.cfc differs from the default MXUnit one, however, in that it copies any arguments passed in to variables scope. This offers an advantage of easiy implementation, but the method is still generally over-written with a custom "setUp" method.

Transactions

To run a test method in a rollback transaction, pass the method into the "runInRollbackTransaction" method. This can be done by making a private version of a method with no "hint" (but holding all of the test logic) and a public version with a "hint" that just calls the private method.

Watch for Changes!

The implementation of handling rollback transations may change. Ideally this could be done without writing two different methods.

Data

RecordsTester removes much of the tedium of dealing with data during unit testing.

saveTestRecord(comp,data)
This method takes the Records component to which to save data and an optional structure of data to save. It will save random data for all of the fields in the data set - using any data provided in the structure in place of the random data (uses getRandomData).
getRandomData(comp,data)
Takes a Records component and optional data structure. Returns random data for all of the fields in the data set - using any data provided in the structure in place of the random data (uses getRandomFieldValue).
getRandomFieldValue(field)
Takes a structure of a field (like from getFieldsStruct) and returns a random value for that field type (uses getRandomValue).
getRandomValue(datatype)
Takes datatype and returns a random value.

Email

If you use NoticeMgr or Mailer to send email from components, then RecordsTester has some methods to help test that.

When testing any email, it is recommended to first call "assertEmailTestable()" (which calls isEmailTestable) so that any failure will be given for the right cause.

Email assertions:

assertEmailTestable()
This should be used at the top of any method testing email to verify that RecordsTester can even test email sending.
assertEmailSent(when)
This verifies that an email has been sent. Any additional arguments will check for matching arguments for Mailer.send() (uses isEmailSent).
assertEmailNotSent(when)
This verifies that an email has not been sent. Any additional arguments will check for matching arguments for Mailer.send() (uses isEmailSent).
assertNoticeSent(notice,to,when)
This verifies that a notice email has been sent. Any additional arguments will check for matching arguments for Mailer.send() (uses isNoticeSent).
assertNoticeNotSent(notice,to,when)
This verifies that a notice email has not been sent. Any additional arguments will check for matching arguments for Mailer.send() (uses isNoticeSent).

Other Email Methods:

isEmailSent(when)
Returns a boolean if an email matching the given arguments was sent around the time given.
isNoticeSent(notice,to,when)
Returns a boolean if a notice matching the given argument was sent around the time given.

Example

Here is an example of a component written to test that saving a record on a "Employees" component should send a confirmation email to that employee:

<cfcomponent displayname="Employees" extends="com.sebtools.RecordsTester">

<cffunction name="setUp" access="public" returntype="void" output="no">
	
	<cfset loadExternalVars("Employees")>
	<cfset loadExternalVars(varlist="NoticeMgr",skipmissing=true)>
	
</cffunction>

<cffunction name="shouldSaveSendConfirmationEmail" access="public" returntype="void" output="no" hint="An employee should get a confirmation email any time is record is saved.">
	
	<cfset runInRollbackTransaction(doshouldCheckMailForwardUnhandledEmail)>
	
</cffunction>

<cffunction name="doshouldSaveSendConfirmationEmail" access="private" returntype="void" output="no" hint="The actual code to test shouldCheckMailForwardUnhandledEmail">
	
	<cfset var employeeid = 0>
	<cfset var qEmployee = 0>
	
	<cfset assertEmailTestable()>
	
	<cfset employeeid = saveTestRecord(variables.Employees)>
	<cfset qEmployee = variables.Employees.getRecord(employeeid)>
	
	<cfset assertNoticeSent(notice="Employee Saved",to=qEmployee.Email,when=now())>
	
	
</cffunction>

</cfcomponent>