Created
July 6, 2011 02:36
-
-
Save joelhooks/1066415 to your computer and use it in GitHub Desktop.
Delegating at the Boundaries to Create a Testable Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.probertson.data.QueuedStatement; | |
public interface ISQLRunnerDelegate | |
{ | |
function get numConnections():int; | |
function get connectionErrorHandler():Function; | |
function set connectionErrorHandler(value:Function):void; | |
function execute(sql:String, parameters:Object, handler:Function, itemClass:Class = null, errorHandler:Function = null):void; | |
function executeModify(statementBatch:Vector.<QueuedStatement>, resultHandler:Function, errorHandler:Function, progressHandler:Function = null):void; | |
function close(resultHandler:Function, errorHandler:Function = null):void; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MockStatusSQLRunnerDelegate extends MockSQLRunnerDelegateBase implements ISQLRunnerDelegate | |
{ | |
public function execute(sql:String, parameters:Object, handler:Function, itemClass:Class = null, errorHandler:Function = null):void | |
{ | |
lastStatementExecuted = sql; | |
allStatementsExecuted.push(lastStatementExecuted); | |
parametersSent = parameters; | |
switch (sql) | |
{ | |
case SQLStatusService.LOAD_ALL_STATUSES_SQL: | |
handler.call(null, loadAllStatuses()); | |
break; | |
} | |
} | |
private function loadAllStatuses():SQLResult | |
{ | |
return new SQLResult([new Status()], 1, true, 1); | |
} | |
public function executeModify(statementBatch:Vector.<QueuedStatement>, resultHandler:Function, errorHandler:Function, progressHandler:Function = null):void | |
{ | |
lastStatementExecuted = statementBatch[0].statementText; | |
allStatementsExecuted.push(lastStatementExecuted); | |
parametersSent = statementBatch[0].parameters; | |
} | |
public function get numConnections():int | |
{ | |
return 0; | |
} | |
public function get connectionErrorHandler():Function | |
{ | |
return null; | |
} | |
public function set connectionErrorHandler(value:Function):void | |
{ | |
} | |
public function close(resultHandler:Function, errorHandler:Function = null):void | |
{ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is a more robust mock for the SQLRunnerDelegate to test for | |
* side effects that occur when methods are called on SQLTaskService | |
*/ | |
public class MockTaskSQLRunnerDelegate extends MockSQLRunnerDelegateBase implements ISQLRunnerDelegate | |
{ | |
public function execute(sql:String, parameters:Object, handler:Function, itemClass:Class = null, errorHandler:Function = null):void | |
{ | |
lastStatementExecuted = sql; | |
allStatementsExecuted.push(lastStatementExecuted); | |
parametersSent = parameters; | |
switch (sql) | |
{ | |
case SQLTaskService.LOAD_ALL_TASKS_SQL: | |
handler.call(null, loadTask()); | |
break; | |
case SQLTaskService.LOAD_TASK_SQL: | |
handler.call(null, loadTask()); | |
break; | |
default: | |
break; | |
} | |
} | |
private function loadTask():SQLResult | |
{ | |
var task:Task = new Task(); | |
var data:Array = [task]; | |
var result:SQLResult = new SQLResult(data); | |
task.taskId = 1; | |
task.statusId = 1; | |
return result; | |
} | |
public function executeModify(statementBatch:Vector.<QueuedStatement>, resultHandler:Function, errorHandler:Function, progressHandler:Function = null):void | |
{ | |
lastStatementExecuted = statementBatch[0].statementText; | |
allStatementsExecuted.push(lastStatementExecuted); | |
parametersSent = statementBatch[0].parameters; | |
switch (lastStatementExecuted) | |
{ | |
case SQLTaskService.SAVE_TASK_SQL: | |
resultHandler.call(null, saveTask()); | |
break; | |
} | |
} | |
private function saveTask():Vector.<SQLResult> | |
{ | |
var task:Task = new Task(); | |
var result:SQLResult = new SQLResult([task], 1, true, 1); | |
var results:Vector.<SQLResult> = new Vector.<SQLResult>(); | |
task.taskId = task.statusId = 1; | |
results.push(result); | |
return results; | |
} | |
public function get numConnections():int | |
{ | |
return 0; | |
} | |
public function get connectionErrorHandler():Function | |
{ | |
return null; | |
} | |
public function set connectionErrorHandler(value:Function):void | |
{ | |
} | |
public function close(resultHandler:Function, errorHandler:Function = null):void | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is a delegate for the SQLRunner class that allows us to utilize an interface | |
* for the purposes of creating mocks. The actual SQLRunner class does not express | |
* an interface. This approach also allows us to encapsulate the usage of a 3rd party | |
* library into this single delegate. | |
* | |
* <p>An alternative would be to fork and modify the original library, which would | |
* definitely be a viable option and would help others in the future.</p> | |
*/ | |
public class SQLRunnerDelegate implements ISQLRunnerDelegate | |
{ | |
private var sqlRunner:SQLRunner; | |
public function SQLRunnerDelegate(dataBaseFile:File, maxPoolSize:int = 5) | |
{ | |
sqlRunner = new SQLRunner(dataBaseFile, maxPoolSize); | |
} | |
public function get numConnections():int | |
{ | |
return sqlRunner.numConnections; | |
} | |
public function get connectionErrorHandler():Function | |
{ | |
return sqlRunner.connectionErrorHandler; | |
} | |
public function set connectionErrorHandler(value:Function):void | |
{ | |
sqlRunner.connectionErrorHandler = value; | |
} | |
public function execute(sql:String, parameters:Object, handler:Function, itemClass:Class = null, errorHandler:Function = null):void | |
{ | |
sqlRunner.execute(sql, parameters, handler, itemClass, errorHandler); | |
} | |
public function executeModify(statementBatch:Vector.<QueuedStatement>, resultHandler:Function, errorHandler:Function, progressHandler:Function = null):void | |
{ | |
sqlRunner.executeModify(statementBatch, resultHandler, errorHandler, progressHandler); | |
} | |
public function close(resultHandler:Function, errorHandler:Function = null):void | |
{ | |
sqlRunner.close(resultHandler, errorHandler); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SQLStatusService extends Actor implements IStatusService | |
{ | |
[Inject] | |
public var sqlRunner:ISQLRunnerDelegate; | |
[Inject] | |
public var statusListModel:StatusListModel; | |
public function loadStatuses():void | |
{ | |
statusListModel.reset(); | |
sqlRunner.execute(LOAD_ALL_STATUSES_SQL, null, loadStatusesResultHandler, Status, databaseFaultHandler); | |
} | |
private function loadStatusesResultHandler(result:SQLResult):void | |
{ | |
statusListModel.statuses = new ArrayCollection(result.data); | |
dispatch(new StatusesLoadedEvent()); | |
} | |
private function databaseFaultHandler(error:SQLError):void | |
{ | |
dispatch(new DatabaseErrorHandlerEvent(error.message)); | |
} | |
[Embed(source="/assets/data/sql/statuses/LoadAllStatuses.sql", mimeType="application/octet-stream")] | |
private static const LoadAllStatusesStatementText:Class; | |
public static const LOAD_ALL_STATUSES_SQL:String = new LoadAllStatusesStatementText(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment