I am writing tests for a directive's controller whose startup logic requires some one-way bound parameters to be defined. I am facing difficulties passing one-way bound parameters to the mocked controller. text-bound parameters are passed without difficulty.
NOTE: In the following code, I skip module injections and other irrelevant parts of the code
Here is the directive's definition with two types of parameters:
function DummyDirective() {
return {
restrict: 'E',
scope: {},
bindToController:
oneWay: '&',
text: '@'
},
templateUrl: 'path/to/template.html',
controller: 'GreatController',
controllerAs: 'vm'
};
}
And here is the controller:
function GreatController() {
var vm = this;
vm.treasure = '';
activate();
function activate() {
vm.treasure = fantastic(vm.oneWay);
}
function fantastic(crap) {
if(crap.stack) return 'gold';
}
}
As for the test:
var controller, $rootScope, $scope;
beforeEach(inject(function(_$controller_, _$rootScope_){
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
controller = _$controller_(
'GreatController',
{$scope: $scope},
{text: 'toGoodToBeTrue',
oneWay: {
stack: 'lotsOfIt',
}
}
);
}));
it('should do the job', function(){
expect(controller.treasure).toBe('gold');
});
While text
is properly passed to $controller, oneWay
is undefined and the test fails. I have also tried to pass it a function returning an object to no avail. The documentation does not cover one-way bound parameters. Would you know how to do this without testing the directive and passing parameters as markup? In general I like to keep my tests focused and test directives and their controllers separately.
What if make oneWay optional, adding question mark to its definition: