Angularjs 更改提供服务值以测试不同的案例

Angularjs 更改提供服务值以测试不同的案例,angularjs,unit-testing,mocking,Angularjs,Unit Testing,Mocking,我正在测试一个模态行为,根据用户的操作,模态的结果可以返回几个选项 代码基础如下: const modalInstance = this.$uibModal.open({ animation: true, resolve: {}, component: 'modalView', size: 'lg' }); let dismissed = false; modalInstance.result.then((result) =

我正在测试一个模态行为,根据用户的操作,模态的结果可以返回几个选项

代码基础如下:

const modalInstance = this.$uibModal.open({
      animation: true,
      resolve: {},
      component: 'modalView',
      size: 'lg'
    });
    let dismissed = false;
    modalInstance.result.then((result) => {
      if (result.redirect) { 
        this.redirectToBrowseIfReverted();
      } else {
        this.redirectToSaveTarget();
      }
    },
    () => {
      dismissed = true;
    });
因此,根据重定向的真假,它将调用
redirectToBrowseIfReverted
redirectToSaveTarget
。要开始测试,我只需通过
angular.mock.module
注入
module
,并根据需要将
$uibModal
服务传递给
$provide
模拟:

let mockModal = () => ({
  open: () => {
    return { result: $q.resolve({ redirect: true }) };
 }
});

beforeEach(() => {
 angular.mock.module(moduleName, $provide => {
 $provide.service('$uibModal', mockModal);
});

这当然会将
redirect
值返回为
true
,并调用
redirectToBrowseFreeverted
,但我想在
为false
时测试该情况,但我不知道如何在特定UT情况下告诉angular覆盖
$provide
服务并返回
false
。非常感谢您提供的任何帮助。

不幸的是,您没有提到正在使用的测试框架

如果是Jasmine,您可以使用spy(请参阅)动态更改返回值

您必须将服务注入测试,如下所示:

var $uibModal;
var $q

beforeEach(angular.mock.inject(function(_$uibModal_, _$q_) {
  $uibModal = _$uibModal_;
  $q = _$q_;
}));
然后您可以在测试中使用间谍:

it('should return redirect as true', function() {
  spyOn($uibModal, 'open').and.returnValue({
    result: $q.resolve({ redirect: true })
  });
  <the rest of your test>
});

it('should return redirect as false', function() {
  spyOn($uibModal, 'open').and.returnValue({
    result: $q.resolve({ redirect: false })
  });
  <the rest of your test>
});

因为间谍只能有一个单一的执行策略,所以它会采取最后一个。虽然有点粗糙,但它很管用。

谢谢你,伙计!我使用的是
spyOn
,但用的方法不好,我监视的是服务,而不是控制器的
scope
spyOn($uibModal,'open')。和.returnValue({result:$q.resolve({redirect:false})})
而不是
spyOn(controller.$uibModal,'open')。和.returnValue({result:$q.resolve({redirect:false})})毕竟我在构造函数上设置了模式服务,使其在控制器作用域上可用:
构造函数($uibModal,$rootScope,$scope,$timeout,$q){this.$uibModal=$uibModal;..
感谢您的解决方案!
var $uibModal;
var $q;
var modalSpy;

beforeEach(angular.mock.inject(function(_$uibModal_, _$q_) {
  $uibModal = _$uibModal_;
  $q = _$q_;
  modalSpy = spyOn($uibModal, 'open').and.returnValue({
    result: $q.resolve({ redirect: true })
  });
}));

it('returns false for this one test only', function() {
  modalSpy.and.returnValue({
    result: $q.resolve({ redirect: false })
  });
});