Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在AngularJS工厂方法中模拟对象_Angularjs_Mocking_Angularjs Factory - Fatal编程技术网

如何在AngularJS工厂方法中模拟对象

如何在AngularJS工厂方法中模拟对象,angularjs,mocking,angularjs-factory,Angularjs,Mocking,Angularjs Factory,我已经创建了一个Angular工厂,该工厂具有处理将代码保存到服务器的方法。其中一个factory方法包含第三方对象,该对象具有执行实际调用的方法。我想测试这段代码,但我无法解决如何模拟第三方对象 用茉莉花测试 我这次测试的目的只是成功地让代码使用我的mock对象,而不是第三方savingUtils对象。可能吗 var app = angular.module("MyApp", []); app.factory("SavingUtils", function() { return {

我已经创建了一个Angular工厂,该工厂具有处理将代码保存到服务器的方法。其中一个factory方法包含第三方对象,该对象具有执行实际调用的方法。我想测试这段代码,但我无法解决如何模拟第三方对象

用茉莉花测试

我这次测试的目的只是成功地让代码使用我的mock对象,而不是第三方savingUtils对象。可能吗

var app = angular.module("MyApp", []);

app.factory("SavingUtils", function() {

  return {

    saveStuff: function() {
      if(typeof ThirdPartySavingUtils !== "undefined") {
        return ThirdPartySavingUtils.value;
      }
    }
  };
});
这是我的茉莉花测试

describe("Mocking Test", function() {

  var ThirdPartySavingUtilsMock;
  var SavingUtils;

  beforeEach(function() {

    angular.mock.module("MyApp", function($provide) {

      ThirdPartySavingUtilsMock = {
        value: "I am the mock object"
      };

      $provide.value("ThirdPartySavingUtils", ThirdPartySavingUtilsMock);
    });

    inject(function(_SavingUtils_) {
      SavingUtils = _SavingUtils_;
    });
  });

  it("should run without throwing an exception", function() {

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

  it("should mock out ThirdPartySavingUtils with ThirdPartySavingUtilsMock", function() {

    var result = SavingUtils.saveStuff();

    expect(result).toEqual("I am the mock object");
  });
});

你确实有一些选择,但很可能你需要同时做这两件事

1) 您可以创建一个角度服务来包装这个第三方对象——这样您就可以得到一个很好的抽象,以备您需要更改第三方对象时使用

2) 您可以使用类似的模拟框架,它使您能够模拟方法并进行calledOnce等断言

下面是一个使用sinon的模拟测试的链接

您可以基本上看到sinon被用作模拟对象方法的沙箱。Sinon为这些模拟方法提供了额外的属性,因此您可以断言它们是否被调用,调用它们的参数甚至是调用的顺序。它是一个非常非常重要的测试工具

describe('validationManager', function () {
        beforeEach(inject(function ($injector) {
            sandbox = sinon.sandbox.create();
            $rootScope = $injector.get('$rootScope');
            $compile = $injector.get('$compile');
            $q = $injector.get('$q');
            defer = $q.defer();
            validator = $injector.get('validator');
            validationManager = $injector.get('validationManager');

            sandbox.stub(validator, 'makeValid');
            sandbox.stub(validator, 'makeInvalid');
            sandbox.stub(validator, 'getErrorMessage').returns(defer.promise);

            setModelCtrl();
        }));

        afterEach(function () {
            sandbox.restore();
            setModelCtrl();
        });

        it('should be defined', function () {
            expect(validationManager).to.exist;
        });

        describe('validateElement', function () {
            it('should return if no $parsers or $formatters on the controller', function () {
                validationManager.validateElement(modelCtrl);
                expect(validator.makeValid.called).to.equal(false);
                expect(validator.makeInvalid.called).to.equal(false);
            });

});
编辑-----------------------

在这里,这是对您的代码的实践(我没有运行它,但它给出了一般的想法)

测试

(function (angular, sinon) {
    'use strict';

    describe('MyApp.SavingUtils', function () {
       var sandbox, thirdPartyApi, SavingUtils, thirdPartyApiValue = 2;

        beforeEach(inject(function ($injector) {
            sandbox = sinon.sandbox.create();
            thirdPartyApi = $injector.get('thirdPartyApi');
            SavingUtils = $injector.get('SavingUtils');

            // stub the method and when called return a simple object or whatever you want
            sandbox.stub(thirdPartyApi, 'save').returns({ id: 1});
            sandbox.stub(thirdPartyApi, 'value', function () {
                return thirdPartyApiValue;
            });
        }));

        afterEach(function () {
            // This removes those stubs and replace the original methods/values
            sandbox.restore();
        });

        describe('save', function () {
            it('should return call the save method on thirdPartyApi', function () {
                var item = {};
                SavingUtils.save(item);

                expect(thirdPartyApi.save.calledOnce).to.equal(true);
            });
        });

        describe('getValue', function () {
            it('should return value of value property on thirdPartyApi', function () {
                var result = SavingUtils.getValue();

                expect(result).to.equal(thirdPartyApiValue);
            });
        });
    });
}(angular, sinon));

感谢您的回答和示例代码。我将不得不看看Sinon,并尝试用服务包装第三方代码。你能告诉我我尝试的方式有什么问题吗?有没有可能像我尝试的那样模仿那个物体?Thanks@Joe查看编辑-很高兴看到您正在考虑测试!
(function (angular, sinon) {
    'use strict';

    describe('MyApp.SavingUtils', function () {
       var sandbox, thirdPartyApi, SavingUtils, thirdPartyApiValue = 2;

        beforeEach(inject(function ($injector) {
            sandbox = sinon.sandbox.create();
            thirdPartyApi = $injector.get('thirdPartyApi');
            SavingUtils = $injector.get('SavingUtils');

            // stub the method and when called return a simple object or whatever you want
            sandbox.stub(thirdPartyApi, 'save').returns({ id: 1});
            sandbox.stub(thirdPartyApi, 'value', function () {
                return thirdPartyApiValue;
            });
        }));

        afterEach(function () {
            // This removes those stubs and replace the original methods/values
            sandbox.restore();
        });

        describe('save', function () {
            it('should return call the save method on thirdPartyApi', function () {
                var item = {};
                SavingUtils.save(item);

                expect(thirdPartyApi.save.calledOnce).to.equal(true);
            });
        });

        describe('getValue', function () {
            it('should return value of value property on thirdPartyApi', function () {
                var result = SavingUtils.getValue();

                expect(result).to.equal(thirdPartyApiValue);
            });
        });
    });
}(angular, sinon));