为什么我的业力单元测试失败了"意外请求"?

时间:2014-07-26 22:25:28

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

我的单元测试都失败了:

Error: Unexpected request: GET views/partials/listings.html`.

我一直在阅读这个问题:Jasmine tests AngularJS Directives with templateUrl,但在使用ngMockE2E $httpBackend而不是ngMock $httpBackend时,讨论似乎解决了这个问题。我试过使用接受的答案中提到的.passThrough()方法,但是我收到了这个错误:

TypeError: '$httpBackend.whenGET('views/partials/listings.html').passThrough' is not a function`

似乎passThrough()方法仅适用于ngMockE2E $httpBackend

我编写了我的测试来模仿AngularJS教程中的phonecatApp XHR test。这是我正在进行的测试:

(function() {
  'use strict';
  describe('Controller: ListingsCtrl', function() {
    var $httpBackend, ListingsCtrl, scope;
    $httpBackend = false;
    ListingsCtrl = false;
    scope = {};
    beforeEach(module('app'));
    beforeEach(inject(function(_$httpBackend_, $controller, $rootScope) {
      $httpBackend = _$httpBackend_;
      scope = $rootScope.$new();
      ListingsCtrl = $controller('ListingsCtrl', {
        $scope: scope
      });
      $httpBackend.expectGET('/api/listings/active').respond([
        {
          address: '123 Fake St'
        }, {
          address: '456 Other Ave'
        }
      ]);
    }));
    afterEach(function() {
      $httpBackend.verifyNoOutstandingExpectation();
      $httpBackend.verifyNoOutstandingRequest();
    });
    it('should have the correct default search parameters', function() {
      $httpBackend.flush();
      expect(scope.beds).toBe('Any');
      expect(scope.maxRent).toBe('None');
      expect(scope.search.address).toBe('');
      expect(scope.search.side).toBe('');
    });
    it('should have listings after loading them from the API', function() {
      expect(scope.listings.length).toBe(0);
      $httpBackend.flush();
      expect(scope.listings.length).toBeGreaterThan(0);
    });
  });

}).call(this);

我测试的所有四个浏览器(Opera,Safari,Firefox和Chrome)中的两个测试都失败了,并显示相同的错误消息。

我认为使用karma进行单元测试只会加载控制器代码,因此不会尝试加载任何视图或模板。我错了吗?

1 个答案:

答案 0 :(得分:1)

好吧,我认为这里存在很多混乱,让我解开这个问题。在深入研究技术细节之前,这里有单元测试的一些理想特性:

  • 我们希望我们的单元测试快速。快速燃烧。原因是我们经常要经常进行单元测试(你做TDD,对吧?)。
  • 单元测试设置应尽可能简单。原因是我们希望整个过程尽可能简单。否则,人们将倾向于跳过测试,我们不希望在代码中出现错误。

假设我们希望我们的测试易于设置快速运行,那么在使用模板测试指令时,应该通过HTTP提供模板。这样做会使整体设置变得更加复杂(您需要设置WWW服务器来提供模板,获取路径"正确"等等)并且会减慢测试速度(额外的,异步HTTP请求+网络流量)运行测试)。

你应该做的是预加载指令'模板到$templateCache 。最简单的方法是使用karma-ng-html2js-preprocessor。这个预处理器可以获取HTML文件,将它们串联为JS并放入$templateCache。如果您正在寻找使用此方法的完整项目设置,您可以在此处找到一个很好的示例:https://github.com/vojtajina/ng-directive-testing

总结:不要在测试设置中混合单元测试和e2e模拟。这使得它更复杂,运行速度更慢。将指令模板预加载到$templateCache,而不是完全避免与$http的任何交互。