AngularJS $窗口:如何在单元测试中获益? (与使用窗口相比)

时间:2017-12-07 16:47:08

标签: javascript angularjs unit-testing

虽然官方文档说,

  

虽然JavaScript在JavaScript中是全局可用的,但它会导致可测性问题,因为它是一个全局变量。在AngularJS中,我们总是通过$ window服务引用它,因此可以覆盖,删除或模拟测试。

我仍然无法理解它。如何在单元测试代码中从$window中受益?在下面的代码片段中,我可以使用或不使用$window来监视/模拟并使用本机窗口对象。它是如何导致可测性问题的?

angular.module('messagePopper', [])
  .factory('popper', function popperFactory($window) {
    return {
      popupMessage(message) {
        alert(message);
      },

      popupMessageWith$window(message) {
        $window.alert(message);
      }
    };
  });

describe('messagePopper: popper service', () => {
  let $injector;
  let $window;
  let popper;

  beforeEach(() => {
    module('messagePopper');

    inject((_$injector_) => {
      $injector = _$injector_;
      $window = $injector.get('$window');
      popper = $injector.get('popper');
    });
  });

  it('should popupMessage correctly', () => {
    const message = 'welcome glenn@foodie.net';

    const alertMock = spyOn(window, 'alert');

    popper.popupMessage(message);

    expect(alertMock)
      .toHaveBeenCalledWith(message);
  });

  it('should popupMessageWith$window correctly', () => {
    const message = 'welcome glenn@foodie.net';

    const alertMock = spyOn($window, 'alert');

    popper.popupMessageWith$window(message);

    expect(alertMock)
      .toHaveBeenCalledWith(message);
  });
});

在这里小提琴:https://jsfiddle.net/glenn/x42uex66

1 个答案:

答案 0 :(得分:1)

使用全局窗口对象时,有时候测试会失败,导致windows对象无法清除以进行下一次测试。在这种情况下,您会突然看到很多测试因为看似没有理由而失败,而不仅仅是导致问题的一个测试。