Angular / Karma:模拟数据未定义

时间:2015-11-22 19:54:34

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

我正在尝试创建一个单元测试来检查GET请求是否返回正确数量的项目,但我正在使用模拟数据来执行此操作。

我的测试看起来像这样:

test.js

describe('Customer Controller', function () {
    var controller;
    var customers = mockData.getMockCustomers(); // fake customers (5 customers)

    beforeEach(function() {
      bard.appModule('app');
      bard.inject('$controller', '$q', '$rootScope');

      var cs = {
        getCustomers: function() {
          return $q.when(customers);
        }
      };

      controller = $controller('customersCtrl', {
        CustomerService: cs
      });
    });

    it('should return 5 customers', function() {
      $rootScope.$apply();
      expect(controller.customers).to.have.length(5);
    });
});

我在运行测试时遇到此错误:

  

TypeError:无法读取未定义的属性“length”

由于某种原因,controller.customers看起来像undefined。我是否正确地模拟了数据?

我对此很陌生,无法弄清楚我做错了什么。我甚至不知道如何调试这样的问题。

感谢任何帮助。提前谢谢!

更新

我的控制器看起来像这样:

function customersCtrl(dataservice) {
  var vm = this;
  vm.customers = [];

  fetchCustomers();

  function fetchCustomers() {
    return dataservice.getCustomers()
    .then(function(data) {
      vm.customers = data.data;
      return vm.customers ;
    });
  }
}

更新2

我在测试中放了一个console.log,我的customers变量返回了5个看似空的对象。也许这就是问题?

enter image description here

2 个答案:

答案 0 :(得分:0)

你看过$ httpBackend吗?单元测试实际上并没有打到你的数据库,如果这是你期待的。你必须模拟自己的回应。

即:

$httpBackend.whenGET(/MyEndPoint).respond([{}, {}, {}]);

然后你可以测试长度为3或任何你想要的

答案 1 :(得分:0)

新答案,建议使用sinon spys

我使用mocha进行一些节点测试,使用chai& amp; sinon - 这是一个使用sinon stub的例子。

var sinon = require('sinon');

describe('Customer Controller', function () {
        var controller;
        var customers = mockData.getMockCustomers(); // fake customers (5 customers)

    beforeEach(function() {
      bard.appModule('app');
      bard.inject('$controller', '$q', '$rootScope');

      var deferred = $q.defer();
      deferred.resolve(customers);
      var cs = {
         fetchCustomers: sinon.stub().returns(deferred.promise)
      };

      controller = $controller('scoreListCtrl', {
        CustomerService: cs
      });
    });

    it('should return 5 customers', function() {
      $rootScope.$apply();
      expect(controller.customers).to.have.length(5);
    });
});

下面的原始答案,建议使用茉莉花间谍

你以前用过茉莉花间谍吗?我会使用它们,这可能不是一个复制粘贴的答案,但应该给你一个大方向。

describe('Customer Controller', function () {
    var controller;
    var customers = mockData.getMockCustomers(); // fake customers (5 customers)

    beforeEach(function() {
      bard.appModule('app');
      bard.inject('$controller', '$q', '$rootScope');

      var cs = {};
      var deferred = $q.defer();
      deferred.resolve(customers);
      spyOn(cs, 'fetchCustomers').and.returnValue(deferred.promise);

      controller = $controller('scoreListCtrl', {
        CustomerService: cs
      });
    });

    it('should return 5 customers', function() {
      $rootScope.$apply();
      expect(controller.customers).to.have.length(5);
    });
});

您可以在此处查看有关茉莉花间谍的更多信息:http://jasmine.github.io/2.0/introduction.html