1

要素を持つテーブルで orderBy をテストするコントローラーの単体テストを作成するのに問題があります。

私は advert.html を持っています:

<body ng-app="motoAdsApp" ng-controller="AdvertsController">

  <form>
    <label>Sort by</label>
    <select ng-model="sortByCol" ng-options="s.name for s in sortByCols">
      <option value=""></option>
    </select>
  </form>

  <br/>

  <table border="1">
    <tr ng-repeat="advert in adverts| orderBy:sortByCol.key">
      <td>
        <span>{{advert.countryName}}, {{advert.regionName}}</span>
      </td>
      <td>{{advert.brandName}}</td>
      <td>{{advert.modelName}}</td>
      <td>{{advert.year}}</td>
      <td>{{advert.price}}</td>
    </tr>
  </table>

</body>

controllers.js:

var motoAdsApp = angular.module('motoAdsApp', []);

motoAdsApp.controller('AdvertsController', ['$scope', function($scope) {

  $scope.sortByCols = [{
    "key": "year",
    "name": "Year"
  }, {
    "key": "price",
    "name": "Price"
  }];

  $scope.adverts = [];
  var allAdverts = ADVERTS_RESPONSE;

  $scope.filter = {
    brandName: null,
    modelName: null,
    country: null,
    region: null,
    yearFrom: null,
    yearTo: null
  };

  $scope.$watch('filter', filterAdverts, true);

  function filterAdverts() {
    $scope.adverts = [];
    angular.forEach(allAdverts, function(row) {
      if (!$scope.filter.country) {
        $scope.filter.region = null;
      }
      if ($scope.filter.brandName && $scope.filter.brandName !== row.brandName) {
        return;
      }
      // ...
      $scope.adverts.push(row);
    });
  }

}
]);

私の単体テスト controllersSpec.js:

describe('MotoAds controllers', function() {

  beforeEach(function() {
    this.addMatchers({
      toEqualData: function(expected) {
        return angular.equals(this.actual, expected);
      }
    });
  });

  beforeEach(module('motoAdsApp'));

  describe('AdvertsController', function() {
    var scope, ctrl, $httpBackend;

    beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
      $httpBackend = _$httpBackend_;
      $httpBackend.expectGET('data/adverts.json').respond(ADVERTS_RESPONSE);

      scope = $rootScope.$new();
      ctrl = $controller('AdvertsController', {$scope: scope});
    }));

  it('should sort by year', function() {
      $httpBackend.flush();

      scope.$apply(function() {
        scope.sortByCol = { key: "year"};
      });

      var prevYear = 0;
      for (var i = 0; i < scope.adverts.length; i++) {
        var advert = scope.adverts[i];
        expect(advert.year).toBeGreaterThan(prevYear);
        prevYear = advert.year;
      }
    });     

  });

});

私のテストを実行した後、私はこれを持っています:

Chrome 30.0.1599 (Windows Vista) MotoAds controllers AdvertsController should so
rt by year FAILED
        Expected 2010 to be greater than 2011.
        Error: Expected 2010 to be greater than 2011.
            at null.<anonymous> (D:/projects/motoads/test/unit/controllers
Spec.js:147:29)
        Expected 2009 to be greater than 2012.
        Error: Expected 2009 to be greater than 2012.

要素(広告)がソートされていないと思います。なんで?どうすればいいですか?

プランカーの例 (実行可能なテストなし)

4

1 に答える 1

4

フィルタは、のorderByような要素で使用された場合、ng-repeat実際にはフィルタ対象の配列オブジェクトをソートしません。配列オブジェクトは変更されませんが、コンパイラがすべての html を作成するために使用する出力配列が変更されます。

したがって、$scope.adverts配列は変更されません。ビューへの出力方法は変更されますが、配列自体は変更されません。

単体テストのこの部分は、E2E テストを使用してテストするものに似ています。コントローラーは、要素がどのように表示されるかはあまり気にしません。それは、ビューに対するより多くの責任です。コントローラーは、データが API から取得されてからビューに渡されるかどうかだけに専念しています。その後、e2e テストは実際にビューをスキャンし、要素が正しくソートされていることを確認できます。

アップデート:

テストでフィルターを呼び出したい場合はorderBy、次のようなものを使用して実行できます。

...
var scope, ctrl, $httpBackend, orderByFilter;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, $filter) {
    $httpBackend = _$httpBackend_;
    $httpBackend.expectGET('data/adverts.json').respond(ADVERTS_RESPONSE);
    orderByFilter = $filter('orderBy');
    scope = $rootScope.$new();
    ctrl = $controller('AdvertsController', {$scope: scope});
}));
...
it('should do something', function(){
    var sortedArray = orderByFilter(scope.adverts, scope.sortByCol.key);
    // do something with the sorted array here
});
...

orderByJavaScript からフィルターにアクセスする方法に関するドキュメントは、こちらにあります。

それが役立つことを願っています。

于 2013-11-04T20:53:28.737 に答える