myApp = angular.module('myApp', [ 'myApp.filters', 'myApp.services' ]);

myApp.services = angular.module('myApp.services', []);
myApp.services.factory('loc', function () {
    return Location.parse(location.href);
});

myApp.filters = angular.module('myApp.filters', []);
myApp.filters.filter('page', function (loc) {
    return function (page) {
        return loc.params(angular.extend(loc.params(), { page : page })).href;
    };
});

services と filters のモジュールをわけて以上のようなのを実装した場合で、page filter をテストしたい場合、以下のようにするとエラーになる。

describe('filter', function () {
	beforeEach(module('myApp.filters'));

	describe('page', function () {
		it('should append page param', function () {
			inject(function (pageFilter) {
				expect(pageFilter(1)).toBe('foobar');
			});
		});
	});
});

//=> Error: [$injector:unpr] Unknown provider: locProvider <- loc <- pageFilter

loc の定義が別モジュールで、beforeEach で該当モジュールを読みこんでいないからだけど、そもそも DI で loc を注入してテストしたいところだと思う。

とりあえず以下のようにしたうまくいった。

describe('filter', function () {
	beforeEach(module('myApp.filters'));

	describe('page', function () {
		it('should append page param', function () {
			module(function ($provide) {
				$provide.factory('loc', function() {
					return Location.parse('http://localhost/foo');
				});
			});

			inject(function (pageFilter) {
				expect(pageFilter(1)).toBe('http://localhost/foo?page=1');
			});
		});
		it('should append page param', function () {
			module(function ($provide) {
				$provide.factory('loc', function() {
					return Location.parse('http://localhost/foo?foo=bar');
				});
			});
			inject(function (pageFilter) {
				expect(pageFilter(1)).toBe('http://localhost/foo?foo=bar&page=1');
			});
		});
	});
});

$provide でテスト用の loc factory を定義してやる。

  1. トップ
  2. tech
  3. AngularJS 依存を持つ filter のテスト