user3284007
user3284007

Reputation: 1717

Unable to use $compile in AngularJS

I'm working on an AngularJS app that uses a custom directive. I'm also trying to use unit testing in my app. So, I'm trying to leverage Jasmine for that. Currently, My unit test is the problem. Currently, it looks like the following:

myDirective.spec.js

describe('Directive: myDirective', function () {
  describe('Function: myProcedure', function () {
    it('should word', function ($rootScope, $compile) {     
      var e = angular.element('<div><br /></div>');
    console.log($compile);
      $compile(e)($rootScope);

      expect(true).toBe(true);
    });
  });
});

This test is throwing an exception. When the console.log line is ran, it prints: 'undefined'. The next line throws an error to Jasmine that says: 'TypeError: undefined is not a function'.

Its like I'm not injecting the $compile service. However, I believe I'm doing so. My test runner looks like the following:

<html ng-app="testApp">
<head>
    <title></title>

    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>

    <script type="text/javascript" src="index.html.js"></script>
    <script type="text/javascript" src="directives/myDirective.js"></script>
    <script type="text/javascript" src="tests/unit/myDirective.spec.js"></script>

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css" />
</head>

<body>

    <a href="#" onclick="env.execute()">run tests</a>

</body>
</html>

Why cannot I not run this basic test? What am I doing wrong?

Upvotes: 2

Views: 5995

Answers (3)

user4516681
user4516681

Reputation: 1

I have come across this problem just now and this is what made my day (in the very end of it actually).just add "module('ng');" along with module('yourAppModule'). It should work.

Upvotes: 0

Ilan Frumer
Ilan Frumer

Reputation: 32357

First you must add angular mocks:

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-mocks.js">
</script>

then load the modules and inject $compile/$rootScope in beforeEach blocks:

describe('Directive: myDirective', function () {
  var $compile;
  var $rootScope;

  beforeEach(module('testApp'));

  beforeEach(inject(function(_$compile_, _$rootScope_){
    $compile = _$compile_;
    $rootScope = _$rootScope_;
  }));

  describe('Function: myProcedure', function () {
    it('should word', function () {     
      var e = angular.element('<div><br /></div>');

      $compile(e)($rootScope);    
      expect(true).toBe(true);

    });
  });
});

Check unit testing docs: http://docs.angularjs.org/guide/dev_guide.unit-testing#directives

Upvotes: 4

bmceldowney
bmceldowney

Reputation: 2305

The it() function provided by jasmine won't do any injection for you, so you need to inject your angular components into your tests. Modify your test as follows:

describe('Directive: myDirective', function () {
  describe('Function: myProcedure', function () {
    it('should word', function () {     
      inject(function ($rootScope, $compile) {
        var e = angular.element('<div><br /></div>');
        //rest of code goes here
      });

You also need a reference to the angular.mocks library.

Upvotes: 0

Related Questions