How do I make fun of $ location.host () in angularjs tests?

I created an Env service that wraps environmental information, and I am currently using $location.host() to determine which environment I'm logging into. How do I mock this in my tests?

I read https://groups.google.com/forum/?fromgroups#!topic/angular/F0jFWC4G9hI but it doesn't seem to work, for example:

 describe("Env (environment) service", function() { var Env; beforeEach(module('App')); beforeEach(inject( ['Env', function(e) { Env = e; }] )); describe("for staging", function() { beforeEach(inject(function($location, $rootScope) { $location.host("http://staging-site.com"); $rootScope.$apply(); })); it("returns envrionment as staging", function() { expect(Env.environment).toEqual("staging"); }); it("returns .isStaging() as true", function() { expect(Env.isStaging()).toBeTruthy(); }); }); }); 

I also tried the $browser option, but that doesn't work either. Any ideas?

+6
source share
4 answers

It is best to use IMHO spies: http://tobyho.com/2011/12/15/jasmine-spy-cheatsheet/

 // inject $location spyOn($location, "host").andReturn("super.domain.com"); var host = $location.host(); alert(host) // is "super.domain.com" expect($location.host).toHaveBeenCalled(); 

The syntax for Jasmine 2.0 and above has changed as follows

 // inject $location spyOn($location, "host").and.returnValue("super.domain.com"); var host = $location.host(); alert(host) // is "super.domain.com" expect($location.host).toHaveBeenCalled(); 
+6
source

I had a similar problem and used the injector service. (I don't know if this is the easiest solution, but it worked for me :))

Since $ location cannot be relied upon during tests, I prepared my own layout. First, you need to create a factory method. (Or service or provider, if you want - see https://gist.github.com/Mithrandir0x/3639232 for comparison):

 function locationFactory(_host) { return function () { return { /* If you need more then $location.host(), add more methods */ host: function () { return _host; } }; }; } 

Then , before you create your "Env" , the feed injector with this layout $ location:

 module(function ($provide) { $provide.factory('$location', locationFactory('http://staging-site.com')); }); 

Now, every time your access to $ location is in your code, your layout is introduced, so it returns everything you need. More on the $ extra method can be found in angular docs

Hope this helps you in the future.

Update: I see one place where you may have been wrong (or at least wrong in my decision). It looks like you are initiating the "Env" module (which, I think, calculates the data immediately), and only after that you change $ location - it may be too late.

+4
source

There is a good example in the document: https://docs.angularjs.org/guide/services

You must ensure that you use $provide before creating an instance of the service. I like to use the $injector in the test file to determine the location first and then instantiate the service.

  var mockLocation; beforeEach(function() { // control the $location.host() function // which we fake in the testcases. mockLocation = { host: jasmine.createSpy() }; module(function($provide) { $provide.value('$location', mockLocation); }); }); 

then

  describe('staging server:', function() { beforeEach(function() { // mockLocation.host.andReturn('http://staging-site.com'); // jasmine 1.x mockLocation.host.and.returnValue('http://staging-site.com'); }); it('returns envrionment as staging', inject(function($injector) { Env = $injector.get('Env'); expect(Env.environment).toEqual('staging'); })); }); 

and

  describe('production server:', function() { beforeEach(function() { // mockLocation.host.andReturn('prod.example.com'); // jasmine 1.x mockLocation.host.and.returnValue('prod.example.com'); }); it('returns envrionment as production', inject(function($injector) { Env = $injector.get('Env'); expect(Env.environment).toEqual('production'); })); }); 
+2
source

Here's another way to mock $ location, with Sinon.js

  locationMock = { path: sinon.spy() }; 

And an example statement:

 locationMock.path.should.be.calledWith('/home'); 
0
source

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


All Articles