为了账号安全,请及时绑定邮箱和手机立即绑定

将模拟注入AngularJS服务

将模拟注入AngularJS服务

狐的传说 2019-10-15 10:28:30
我写了一个AngularJS服务,我想对其进行单元测试。angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).    factory('myService', function ($http, fooService, barService) {    this.something = function() {        // Do something with the injected services    };    return this;});我的app.js文件已注册:angular.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider'])我可以测试DI是否像这样工作:describe("Using the DI framework", function() {    beforeEach(module('fooServiceProvider'));    beforeEach(module('barServiceProvider'));    beforeEach(module('myServiceProvder'));    var service;    beforeEach(inject(function(fooService, barService, myService) {        service=myService;    }));    it("can be instantiated", function() {        expect(service).not.toBeNull();    });});这证明了可以通过DI框架创建服务,但是接下来我要对服务进行单元测试,这意味着要模拟注入的对象。我该怎么做呢?我尝试将模拟对象放入模块中,例如beforeEach(module(mockNavigationService));并将服务定义重写为:function MyService(http, fooService, barService) {    this.somthing = function() {        // Do something with the injected services    };});angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).    factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })但是后者似乎停止了DI所创建的所有服务。有人知道如何模拟单元测试的注入服务吗?
查看完整描述

3 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

您可以使用来将模拟注入服务中$provide。


如果您具有以下具有依赖项的服务,该服务具有名为getSomething的方法:


angular.module('myModule', [])

  .factory('myService', function (myDependency) {

        return {

            useDependency: function () {

                return myDependency.getSomething();

            }

        };

  });

您可以按如下方式注入myDependency的模拟版本:


describe('Service: myService', function () {


  var mockDependency;


  beforeEach(module('myModule'));


  beforeEach(function () {


      mockDependency = {

          getSomething: function () {

              return 'mockReturnValue';

          }

      };


      module(function ($provide) {

          $provide.value('myDependency', mockDependency);

      });


  });


  it('should return value from mock dependency', inject(function (myService) {

      expect(myService.useDependency()).toBe('mockReturnValue');

  }));


});

请注意,由于有调用,$provide.value因此实际上不需要在任何地方显式注入myDependency。它发生在注入myService的过程中。在此处设置嘲讽依赖时,它可能同样容易成为间谍。


查看完整回答
反对 回复 2019-10-15
?
智慧大石

TA贡献1946条经验 获得超3个赞

从我的角度来看,无需自己模拟服务。只需在服务上模拟功能。这样,您就可以像在整个应用程序中一样对您的真实服务进行有角度的注入。然后,使用Jasmine的spyOn功能根据需要在服务上模拟功能。


现在,如果服务本身是一个函数,而不是可以使用的对象spyOn,则还有另一种解决方法。我需要执行此操作,然后发现一些对我来说非常有效的方法。


查看完整回答
反对 回复 2019-10-15
?
精慕HU

TA贡献1845条经验 获得超8个赞

除了John Galambos的回答:如果您只想模拟服务的特定方法,则可以这样做:


describe('Service: myService', function () {


  var mockDependency;


  beforeEach(module('myModule'));


  beforeEach(module(function ($provide, myDependencyProvider) {

      // Get an instance of the real service, then modify specific functions

      mockDependency = myDependencyProvider.$get();

      mockDependency.getSomething = function() { return 'mockReturnValue'; };

      $provide.value('myDependency', mockDependency);

  });


  it('should return value from mock dependency', inject(function (myService) {

      expect(myService.useDependency()).toBe('mockReturnValue');

  }));


});


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 566 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信