user3111277 user3111277 - 1 year ago 115
AngularJS Question

Injecting $attrs in AngularJS

I have some JavaScript written in the context of AngularJS. My relevant JavaScript looks like the following:

.factory('$myFactory', function ($myLibrary, $interpolate) {
return {
myFunction: function ($scope, $attrs, p) {
if (p !== null) {
$attrs.set('myProperty', p);

I am trying to unit test this code. In an attempt to unit test the code, I'm using Jasmine.

it('should set myProperty', inject(function ($scope, $myFactory) {
// $myFactory.myFunction($scope

I can't figure out how to inject some $attrs from my unit test. How do I do that? I can successfully get my $scope setup. However, I don't understand how to inject $attrs. Is there something special about it that I'm not aware of? I'm having a similar issue with $element, though that one is out of the context of this specific test.

Thank you!

Answer Source

Here is a plunker:

Maybe there is a better solution but That's what I got.

  • $scope is easy to get, you can inject $rootScope everywhere
  • $attrs on the other hand is only available through the $compile variable (it lives in compile.js)

My solution is to create a fake controller , to compile it and to hijack it's $attrs.

So that's how it looks like:

var injected = null

function fakeController($scope, $attrs, $element){
  injected = {}
  injected.$scope = $scope;
  injected.$attrs = $attrs;
  injected.$element = $element;

describe('Testing a Hello World controller', function() {
  var $scope = null;
  var $attrs = null;
  var $element = null;

  var ctrl = null;

  //you need to indicate your module in a test

  beforeEach(inject(function($compile, $rootScope, $controller) {

    $compile('<span ng-controller="fakeController"></span>')($rootScope);

    $scope = injected.$scope;
    $attrs = injected.$attrs;
    $element = injected.$element;

    ctrl = $controller('MainCtrl', {
      $scope: $scope,
      $attrs: $attrs,
      $element: $element


  it('should say hallo to the World', function() {