mercredi 25 novembre 2015

trigger scope.$watch again in tests

I have a directive who has a listener, if a model changes when customerFormFactory.setModel() is called( in my controller who is using the directive ) the $watch in my directive is triggered. the collapseHeader is also triggered depending if the if statement passes.

function customerForm ( apiService, $q, adminService, _, customerFormFactory,  $anchorScroll ) {

    function link ( scope, element ) {

        function watchModelChange () {
            scope.$watch( function () {
                return customerFormFactory.getModel();
            }, function ( data ) {
                scope.details = data || {};
                if ( _.has( scope.details, 'id' ) || _.has( scope.details, 'cu_id' ) ) {
                    collapseHeader();
                }
            } );
        }
    } );
} );

my factory: angular .module( 'app.components' ) .factory( 'customerFormFactory', customerFormFactory );

/* @ngInject */
function customerFormFactory () {
    var modelDetails = {};

    var service = {
        'getModel'  : getModel,
        'setModel'  : setModel
    };

    function getModel () {
        return modelDetails;
    }

    function setModel ( customer, scope ) {
        modelDetails = customer;
        if ( scope ) {
            scope.formSettings.show = true;
        }
    }
}

what I want to do is to trigger the $watch statement again to test different scenarios on my unit tests but I do not know how.

I have tried these solutions: How would I test a $scope.watch (AngularJS) change in Jasmine? scope.$watch does not get triggered after scope.$digest in karma unit test some tells me to use scope.$apply but it does not work. but I get an error thrown:

TypeError: 'undefined' is not an object (evaluating 'scope.$apply')

this is my test:

describe( 'customer-form:directive', function ( customerFormFactory ) {

    var scope;
    var element;
    var controller;
    var customers = mockData.getMockCustomers().data;
    var countries = mockData.getMockCountries();

    beforeEach( function () {
        bard.appModule( 'app.components' );
        bard.inject( '$compile', '$rootScope', '$httpBackend', '$controller' );
    } );

    beforeEach( function () {
        scope = $rootScope.$new();

        element = angular.element( '<customer-form get-customers="model.getCustomers()" form-settings="model.formSettings"></customer-form>' );
        scope.model = {
            'getCustomers' : function () {
                return customers;
            },

            'formSettings' : {
                'location' : 'navCust',
                'show'     : false
            }
        };
        $compile( element )( scope );
    } );

    bard.verifyNoOutstandingHttpRequests();

    describe( 'when directive compiles successfully', function () {
        it( 'should not equal to undefined.', function () {
            expect( element ).to.not.equal( undefined );
        } );
        // some tests not included here as this is just a snippet..
        describe( 'watchModelChange', function () {

        } );
    } );
} );

Aucun commentaire:

Enregistrer un commentaire