A simple factory corner test that returns static data

How do you mock a simple Factory in AngularJs that returns static data in a Karma unit test?

I have this simple factory, which for example returns static data:

 angular.module('conciergeApp.services') .factory('CurrentUser', function() { return { id: 1, hotel_id: 1, } }); 

I would like to know how to write a Karma test for this?

So far I have this code, but id is not working:

 describe('ReplyCtrl', function() { beforeEach(module('conciergeApp')); beforeEach(module(function($provide) { $provide.service('CurrentUser', function() { return 1; }); })); //Getting reference of the mocked service var mockUtilSvc; inject(function(CurrentUser) { mockUtilSvc = CurrentUser; }); beforeEach(inject(function($rootScope, $controller) { scope = $rootScope.$new(); ctrl = $controller('ReplyCtrl', { $scope: scope }); })); it('should return value from mock dependency', inject(function(mockUtilSvc) { expect(mockUtilSvc()).toEqual(1); })); }); 

This is the error message I get:

 Firefox 41.0.0 (Mac OS X 10.10.0) ReplyCtrl should return value from mock dependency FAILED Error: [$injector:unpr] Unknown provider: mockUtilSvcProvider <- mockUtilSvc 
+5
source share
1 answer

1) You inject in the wrong place. You specify the insert function in your it test, just delete it.

i.e.

 it('should return value from mock dependency', inject(function(mockUtilSvc) { expect(mockUtilSvc()).toEqual(1); })); 

will become

  it('should return value from mock dependency', function() { expect(mockUtilSvc()).toEqual(1); }); 

2) Now the problem is that mockUtilSvc is a service instance and not a function according to your definition, also based on your layout you need to define it as factory (i.e. you return 1 as the factory value and it is not capable new ).

 beforeEach(module(function($provide) { $provide.factory('CurrentUser', function() { return 1; //If you expect factory to be a function then you need to return a function returning 1 here }); })); 

and

 expect(mockUtilSvc).toEqual(1); 

3) You can also write this as:

 $provide.value('CurrentUser', 1); //Provide the instance here right away 

4) Your first inject also in the wrong place. You simply run it, but you do not start and do not assign an instance during each run of the specification. before Each iteration, you need to set the service instance value for your variable, i.e.:

  beforeEach(inject(function(CurrentUser) { mockUtilSvc = CurrentUser; })); 

Test example:

 describe('ReplyCtrl', function() { var mockData = { id: 1234, hotel_id: 1, }, mockUtilSvc, scope, ctrl ; beforeEach(module('conciergeApp', function($provide) { $provide.value('CurrentUser', mockData); })); beforeEach(inject(function(CurrentUser, $rootScope, $controller) { mockUtilSvc = CurrentUser; scope = $rootScope.$new(); ctrl = $controller('ReplyCtrl', { $scope: scope }); })); it('should return value from mock dependency', function() { expect(mockUtilSvc.id).toEqual(mockData.id); }); }); 

Demo

Note. There are other ways to mock and introduce a layout. For example, in this case you really do not need to use $provide.value . Instead, you can create your mock object and pass it during the creation of the controller instance, as you have full control over this to pass the dependency, as shown below:

  ctrl = $controller('ReplyCtrl', { $scope: scope, CurrentUser: mockUtilSvc }); 

In the case of more complex maintenance using methods, you can create a mock like this.

  mockSvc = jasmin.createSpyObj('MyService', ['method1', 'method2']); mockSvc.method1.and.returnValue($q.when(mockData)); //Simulating a promise returned from an $http call in the method. 
+4
source

Source: https://habr.com/ru/post/1234979/


All Articles