Testing CFThrow

Often a CFC will throw a specific error to signify a particular event. Sometimes a developer will need to test to verify a specific message is thrown, and other times they will need to test to verify a specific message is not thrown.

So how does one write a test that passes or fails when an specific exception is thrown? Here is one way it can be done:

MyComponent.cfc

<cfcomponent name="MyComponent">
	
	<cfproperty name="entities" type="array">
	
	<!--- Initialization --->
	<cffunction name="init" access="public" returntype="MyComponent" output="No">
		<cfset setEntities( ArrayNew( 1 ) )>
		<cfreturn THIS>
	</cffunction>
	
	<cffunction name="throwError" access="public" returntype="void" output="No">
		<cfargument name="doThrow" required="Yes" type="boolean">
		
		<cfif ARGUMENTS.doThrow>
			<cfthrow message="Testing CFThrow in CFUnit" type="TestThrow"> 
		</cfif>
		
	</cffunction>
	
</cfcomponent>
And here is the CFUnit test CFC:

TestMyComponent.cfc

<cfcomponent name="TestMyComponent" extends="net.sourceforge.cfunit.framework.TestCase">

	<cffunction name="testThrowError" returntype="void" access="public">
		<cfset var b = false>
		
		<cftry>
			<!--- Generate an error --->
			<cfinvoke component="MyComponent" method="throwError">
				<cfinvokeargument name="doThrow" value="true">
			</cfinvoke>
			
			<!--- Catch error --->
			<cfcatch type="TestThrow">
				<cfset b = true>
			</cfcatch>
		</cftry>
		
		<!--- Verify error was thrown --->
		<cfset assertTrue("Expected error was not thrown", b)>
		
	</cffunction>
	
</cfcomponent>
And here is the test runner template:

index.cfm

<cfsilent>
	<cfset CFUnitRoot = "net.sourceforge.cfunit" />
	
	<cfset tests = ArrayNew(1)>
	<cfset ArrayAppend(tests, "CFUnit.help.throwtest.TestMyComponent")>
	<cfset testsuite = CreateObject("component", "#CFUnitRoot#.framework.TestSuite").init( tests )>
</cfsilent>

<cfoutput>
	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
	
	<html>
	<head>
		<title>CFThrow Test Example</title>
	</head>
	
	<body>
	<h1>Collection Test Example</h1>
	<hr>
	<h2>CFUnit Test</h2>
	<cfinvoke component="#CFUnitRoot#.framework.TestRunner" method="run">
		<cfinvokeargument name="test" value="#testsuite#">
		<cfinvokeargument name="name" value="">
	</cfinvoke>
	</body>
	</html>
</cfoutput>