How to Write Test Case for Handler Using Testbox

A month ago I have posted the testbox example for unit testing and promise to post a example of handler testcase using testbox.

Well, I found significant difference in the handler test case. Like it’s bit difficult to use and access mock of any model, Like we mock the model in unit testing. Also handler testing interect with the database.

Error when loading gists from https://gist.github.com/.

/**

* @Author  Parixit
* @Date 18 July 2016
* @use handler test 
* @handler handlers.company
* UDFLibraryFile ""
*/

component extends="coldbox.system.testing.BaseTestCase" appMapping="/"{
    var testcaseurl = {};
    function beforeAll(){
        super.beforeAll();
        testcaseurl = {"propertiesFilename":"TEST.properties","propertiesSummary":false,"directory":"tests.specs","labels":"","reportpath":"C:\\project\\demo\\tests\\results","recurse":true,"reporter":"simple","testBundles":"tests.specs.integration.companytest","bundles":""};
        ErrBox = getInstance("models.ErrorBox");
    }
    function afterAll(){
        super.afterAll();
    }
    function run(){
        var newid = 0;
        beforeEach( function( currentSpec ){
            setup();
            structClear(cookie);
            ErrBox.clearMessage();
        });
        /* This code will test list function in my company handler*/
        describe( "Function Name : list", function(){
            var requestparam = {};
            beforeEach( function( currentSpec ){
                requestparam = {
                    page:1,
                    pageSize:10,
                    isReset:0,
                    exportType:"",
                    company_name:"Client Company",
                    isReset:1,
                    isSubmit:1,
                    createdBy:1,
                    sortBy:’id’,
                    sortOrder: ‘asc’,
                    rType:”
                }
                setup();
                structClear(URL);
                structAppend(URL,testcaseurl);
            });
            it("Case 1: listCompany with list view",function(){
                structAppend(URL,requestparam);
                var event = execute("company.list");
                var rcollect = event.getCollection();
                /* 
                    event.getCollection() gives you whole rc return by the handler.
                    if you want to get the private collection then just write private=true in the function. like event.getCollection(private=true)

                 */
                expect(    rcollect.qcompany ).toBeStruct(‘Not Struct’);
                expect(    rcollect.qcompany.query ).toBeQuery(‘Not Query’);
                expect(    rcollect.qcompany.query.Recordcount ).toBeGTE(1);
                /* If all goes well then I got struct of query with totalrowcount and query’s rec must be grater then 1 */
                expect(    event.getCurrentView() ).toBe(‘companyList’);
                /* Also check the view that where it render the data. */
            });
        });
        describe( "Function Name : dspEditor", function(){
            var requestparam = {};
            beforeEach( function( currentSpec ){
                requestparam = {
                    companyid:”,
                    company_name:"Test Account Name",
                    industryid:"1",
                    address_1:"This is Test address 1",
                    address_2:"This is test address 2",
                    city:’STL’,
                    state:’24’,
                    county:’1485′,
                    zip:’1465′,
                    phone:’9898989898′,
                    fax:”,
                    website:’https://www.isummation.com’,
                    comments:’This is test comment’
                }
                setup();
                structClear(URL);
                structAppend(URL,testcaseurl);
            });
            it("Case 1: dspEditor in add mode",function(){
                requestparam.companyid=0;
                structAppend(URL,requestparam);
                var event = execute("company.dspEditor");
                var rcollect = event.getCollection();
                expect(    rcollect.header_top ).toBe(‘Add Account’);
                expect(    event.getCurrentView() ).toBe(‘companyAdd’);
            });
            it("Case 2: dspEditor in edit mode",function(){
                requestparam.companyid=1;
                structAppend(URL,requestparam);
                var event = execute("company.dspEditor");
                var rcollect = event.getCollection();
                expect(    rcollect.header_top ).toBe(‘Edit Account’);
                expect(    event.getCurrentView() ).toBe(‘companyAdd’);
            });
        });
        describe( "Function Name : view", function(){
            var requestparam = {};
            beforeEach(function( currentSpec ){
                requestparam = {
                    companyid:1
                };
                setup();
                structClear(URL);
                structAppend(URL,testcaseurl);
            });
            it("Case 1: View with no companyId",function(){
                requestparam.companyId=0;
                structAppend(URL,requestparam);
                var event = execute("company.view");
                var rcollect = event.getCollection();
                /* 
                    If you are using errorbox in the handler then after calling execute method,
                    Whatever set by the handler during execution in the errorbox will be get by following code.
                */
                ErrorBox = ErrBox.getmessage();
                expect(    ErrorBox ).toBeStruct(true);
                expect(    ErrorBox.type ).toBe(‘Error’);
                expect(    arraylen(ErrorBox.Message) ).toBe(1);
                expect(    ErrorBox.Message[1] ).toBe(‘Required parameter missing’);
                expect(    rcollect.setNextEvent_event ).toBe(‘company.list’);
            });
            it("Case 2: View with valid company id",function(){
                structAppend(URL,requestparam);
                var event = execute("company.view");
                var rcollect = event.getCollection();
                expect(    rcollect.ocompanyBean ).toBeStruct("Not Query");
                expect(    rcollect.ocompanyBean.company_name ).toBe(‘test first client company (alpha)’);
                expect(    event.getCurrentView() ).toBe(‘companyview’);
            });
        });
        describe( "Function Name : doSave", function(){
            var requestparam = {};
            beforeEach(function( currentSpec ){
                requestparam = {
                    xehBackLink:’company.list’,
                    companyid:”,
                    company_name:"ABC Company",
                    industryid:"1",
                    address_1:"This is Test address 1",
                    address_2:"This is test address 2",
                    city:’STL’,
                    state:’24’,
                    county:’1485′,
                    zip:’1465′,
                    phone:’9898989898′,
                    fax:”,
                    website:’https://www.isummation.com’,
                    comments:’This is test comment’
                };
                setup();
                ErrBox.clearMessage();
                structClear(URL);
                structAppend(URL,testcaseurl);
            });
            it("Case 1: Save Company with no Account Name and no Zip",function(){
                requestparam.company_name=”;
                zip=”;
                structAppend(URL,requestparam);
                var event = execute("company.doSave");
                var rcollect = event.getCollection();
                ErrorBox = ErrBox.getmessage();
                expect(    ErrorBox ).toBeStruct(true);
                expect(    ErrorBox.type ).toBe(‘Error’);
                expect(    arraylen(ErrorBox.Message) ).toBe(1);
                expect(    ErrorBox.Message[1] ).toBe(‘Account/Company Name is required’);
                expect(    rcollect.setNextEvent_event ).toBe(‘company.dspEditor’);
            });
            it("Case 2: Save Company with valid data",function(){
                transaction{
                    try{
                        structAppend(URL,requestparam);
                        /*
                            Here in this code before inserting the record I need to get the count of records so that
                            I compare count after execution that record inserted or not.
                        */
                        var local.recCount = getCompany().Recordcount;
                        var event = execute("company.doSave");
                        var rcollect = event.getCollection();
                        ErrorBox = ErrBox.getmessage();
                        expect(    ErrorBox ).toBeStruct(true);
                        expect(    ErrorBox.type ).toBe(‘Info’);
                        expect(    arraylen(ErrorBox.Message) ).toBe(1);
                        expect(    ErrorBox.Message[1] ).toBe(‘Record saved successfully’);
                        expect(    rcollect.setNextEvent_event ).toBe(‘company.list’);
                        /* Here I compare that dose record count increase by 1 or not.*/
                        expect(    getCompany().Recordcount ).toBeGTE((local.recCount + 1));
                        rollBackData(getCompany().id);
                        expect(    getCompany().Recordcount ).toBeGTE((local.recCount));
                    }
                    catch(Any e){}
                    finally{
                        /* 
                            Here I rollback the transaction because when I run this testcase again I got the predefine state of database
                        */
                        transaction action=’rollback’;
                    }
                }
            });
        });
    }
    function getCompany(id=0){
        queryObj = new query();
        queryObj.setDatasource("testdb");
        var local.condition = "";
        if(arguments.id){
            queryObj.addParam(name="id",value=id,cfsqltype="NUMERIC");
            local.condition = local.condition & "AND id = :id ";
        }
        return queryObj.execute(sql="SELECT * FROM company WHERE 1 = 1 #local.condition# order by id desc").getResult();
    }
}

Some point need to keep in mind while creating test case.

1) Always consider only the code / function for what you are writing testcase. 

2) Try to rollback all the operation you have made during the testcase execution.