【问题标题】:Angular Karma/Jasmine testing: How to mock a service in controller with promises?Angular Karma/Jasmine 测试:如何用承诺模拟控制器中的服务?
【发布时间】:2017-06-03 07:15:22
【问题描述】:

我正在尝试对我的控制器进行单元测试。我试图单元测试的功能是:

    function myFunction() {

        MyService
            .myMethod(thing1, thing2)
            .then(function handleMyMethod(result) {
                SomeModule.errorHandler(result)
                    .onSuccess(function onSuccess() {
                        // do stuff
                    })
                    .onError(function onError() {
                        // do stuff
                    });
            });
    }

相关测试文件sn-p:

var MockService = {
  myMethod: function(thing1, thing2) {
   var promise = $q.defer().promise;
   return promise;
 }
};

beforeEach(module(function($provide) {
  $provide.value('MyService', MockService);
}));

beforeEach(inject(function (_$controller_, _MyService_, _SomeModule_, ...) {
  ...
  MyService = _MyService_;

  MyController = _$controller_('MyController as Ctrl', {
    $controller: controller,
    MyService: MockService,
  }); 

我对如何编写允许我同时满足 onSuccess 和 onError 情况的测试感到困惑。我试图覆盖两个分支以进行分支覆盖,但不知道语法是如何工作的。

【问题讨论】:

    标签: angularjs unit-testing karma-runner karma-jasmine


    【解决方案1】:

    您可以选择以下两种方式之一:

    1. 您可以编写模拟服务来查看参数并解决错误或成功。
    我的方法:功能(事物1,事物2){ if (thing1=='all good') return $q.when('excellent'); return $q.reject('对不起,芽'); }
    1. 您可以在更接近调用位置的位置覆盖该方法。
    it('成功了', function() { spyOn(MockService, 'myMethod').and.returnValue($q.when('excellent'); $rootScope.$apply( MyController.doStuff('foo'); ); 期望(MyController.someProperty).toEqual('优秀'); }); //等等。

    请注意,您不需要同时使用提供代码覆盖模块注入器并在 $controller locals 参数中提供模拟服务。

    【讨论】:

    • 对于方法#2,除了 $q.when('excellent') 变为 $q.reject('error') 之外,错误情况是否相同?
    • 是的。请注意 $q.reject 并不存在于所有版本的 angularjs 中,因此如果您在 1.2 或其他版本中工作,您可能仍需要使用 $q.defer().reject('error')。
    • 我的角度版本是 1.3,所以看起来我必须使用 $q.defer().reject('error')。我的成功案例有效,但我的错误案例不喜欢 MyController.doStuff('foo');线。我的错误测试用例与成功用例相同,除了 $q.defer().reject('error') 行。我还需要进行其他更改吗?
    • 你是用callFake还是override?​​span>
    • 我使用了 #2,即您提供的替代解决方案。我的控制器中没有任何 callFake。
    猜你喜欢
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2017-02-24
    • 2017-09-04
    • 1970-01-01
    • 2015-07-12
    • 2014-06-17
    相关资源
    最近更新 更多