Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject dependencies in jasmine test for an angular item

Here is the test spec file:

describe('Test main controller', function(){         it('Should initialize value to Loading', function(){             $scope = {}             ctrl =  new mainNavController($scope)             expect($scope.wksp_name).toBe('Loading')         })     }) 

Here is the controller file

function mainNavController($scope) {     $scope.wksp_name = 'Loading...'     $scope.$on('broadCastWkspNameEvent', function (e, args) {         $scope.wksp_name = args     }) }  mainNavController.$inject=['$scope'] 

But my test fails saying Object #<Object> has no method '$on'

I am using the basic setup of jasmine.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd"> <html> <head>   <title>Jasmine Spec Runner</title>    <link rel="shortcut icon" type="image/png" href="testlib/jasmine-1.2.0/jasmine_favicon.png">   <link rel="stylesheet" type="text/css" href="testlib/jasmine-1.2.0/jasmine.css">   <script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine.js"></script>   <script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine-html.js"></script>    <!-- include source files here... -->   <script type="text/javascript" src="/static_files/js/test-specs/main-nav-spec.js"></script>    <!-- include spec files here... -->   <script type="text/javascript" src="/static_files/js/common/jquery/latest.js"></script>   <script type="text/javascript" src="/static_files/js/common/angular/angular-1.0.1.min.js"></script>   <script type="text/javascript" src="/static_files/js/common/angular/angular-resource-1.0.1.min.js"></script>   <script type="text/javascript" src="/static_files/js/section/main-nav-controller.js"></script>    <script type="text/javascript">     (function() {       var jasmineEnv = jasmine.getEnv();       jasmineEnv.updateInterval = 1000;        var htmlReporter = new jasmine.HtmlReporter();        jasmineEnv.addReporter(htmlReporter);        jasmineEnv.specFilter = function(spec) {         return htmlReporter.specFilter(spec);       };        var currentWindowOnload = window.onload;        window.onload = function() {         if (currentWindowOnload) {           currentWindowOnload();         }         execJasmine();       };        function execJasmine() {         jasmineEnv.execute();       }      })();   </script>  </head>  <body> </body> </html> 

What is it that I am doing wrong? I am not able to understand how this thing is supposed to work :)

like image 342
Ranjith Ramachandra Avatar asked Sep 04 '12 09:09

Ranjith Ramachandra


People also ask

How do you mock a service to inject in a unit test?

var service = new MockLoginService(); beforeEachProviders(() => [ provide(TestService, { useValue: service })]); it('should load languages', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { tcb . createAsync(LoginComponent). then((fixture) => { let element = fixture.

How do I unit test a service with Angular components?

Mock Service Dependency In Angular For unit testing the method, you need to mock the service method getPosts to test the component method. Let's start by writing unit test for testing method getPostDetails when the response from service method getPosts is an empty array. Add the following unit test case to the app.

What is dependency injection in testing?

In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends on. A form of inversion of control, dependency injection aims to separate the concerns of constructing objects and using them, leading to loosely coupled programs.

How do I Resolve dependencies in angular testing?

Testing Dependency Injection • Angular We can resolve dependencies in our tests using a number of methods. We can resolve using the the test bed itself, usually in the beforeEach function and store the resolved dependencies for use in our test specs. We can resolve using the inject function at the start of each test spec.

How to resolve multiple dependencies in Jasmine with dependency injection?

The inject function allows us to resolve multiple dependencies by listing their tokens in an array that we pass as an argument. Every dependency injection token is resolved and available to the test case function as a parameter. I have created a StackBlitz project with all the tests from this article running in Jasmine.

What is dependency injection in angular?

Let’s prepare our experimental gear. Cover photo by deepakrit on Pixabay. Original publication date: 2019-04-29. Dependency injection is a key feature of Angular. This flexible approach makes our declarables and class-based services easier to test in isolation.

Which testing framework should I use for angular testing?

Similar to Karma, it’s also the recommended testing framework within the Angular documentation as it’s setup for you with the Angular CLI. Jasmine is also dependency free and doesn’t require a DOM. As far as features go, I love that Jasmine has almost everything I need for testing built into it.


1 Answers

The main problem with your test code is that it tries to create a controller's instance "by hand" using the new operator. When doing so AngularJS has no chance to inject dependencies. What you should be doing is to allow AngularJS inject dependencies:

var $scope, ctrl;  //you need to inject dependencies first beforeEach(inject(function($rootScope) {     $scope = $rootScope.$new();         }));  it('Should initialize value to Loading', inject(function($controller) {     ctrl = $controller('MainNavController', {         $scope: $scope     });     expect($scope.wksp_name).toBe('Loading...'); })); 

Here is the link to a complete jsFiddle: http://jsfiddle.net/pkozlowski_opensource/7a7KR/3/

There are 2 things worth noting in the above example:

  1. You can use the inject() method from the ngMock module to inject dependencies: https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
  2. To create a controller instance (that supports dependency injection) you would use the $controller service: http://docs.angularjs.org/api/ng.$controller

As the last remark: I would advise naming controllers starting with an uppercase letter - this way we won't confuse them with variable names.

like image 114
pkozlowski.opensource Avatar answered Sep 23 '22 06:09

pkozlowski.opensource