私のテストはangular-mock1.5.0で正常に機能しますが、1.5.1ではすべてのテストが次のように失敗します。
TypeError: undefined is not a constructor (evaluating 'angular.element.cleanData(cleanUpNodes)') in ../node_modules/angular-mocks/angular-mocks.js (line 2776)
$$cleanup@../node_modules/angular-mocks/angular-mocks.js:2776:32
$$afterEach@../node_modules/angular-mocks/angular-mocks.js:2746:23
そのコードではコンストラクターが呼び出されていないので、これは奇妙なことです。 おそらくあなたはいくつかのより多くの情報を提供することができますか? 失敗したテストのコピー、できれば実行できるテストのコピー。
ここでテストを見つけることができます。テストは失敗するだけです(バージョン1.5.1、1.5.0のみが問題ありません)。
テストランナーカルマ、テストフレームワークジャスミン。 プロジェクトのセットアップ「FoundationforApps」
https://github.com/HamburgOOU/hoou-webapp/blob/master/test/controllerTest/AboutControllerTest.js
ui-routerを使用しているようですね。
ここで実行するテストを作成してみてください: http ://plnkr.co/edit/tpl:vojSWqpk1yBjQbbPeXRH?
提案として、テストから依存関係を削除して、エラーの正確なトリガーを確認する必要もあります(アプリケーションモジュールには多くの依存関係があります)
はい、angular-ui-router(0.2.18)を使用しています。
Trommorow私はそれを引き起こす依存関係を見つけようとします。
+1、プロバイダーをテストしようとすると、非常によく似たエラーが発生します。
TypeError: 'undefined'は関数ではありません( 'angular.element.cleanData(cleanUpNodes)'を評価しています)
../node_modules/angular-mocks/angular-mocks.js:2776で
../node_modules/angular-mocks/angular-mocks.js:2746で
編集:このエラーはバージョン1.5.1で発生し、1.5.0に戻したところ、すべてが再び機能します。
ここでこれを参照してください: https :
@petebacondarwin undefined is not a constructor
は、定義されていない関数を呼び出そうとしたときにPhantomJSが返す不可解なエラーです。 これは、Chromeのa.something is not a function
エラーに相当します。
Angular / Mock 1.5.1でも同様のエラーが発生しますが、1.5.0では問題になりません。
# PhantomJS
TypeError: undefined is not a constructor (evaluating 'angular.element('<div ng-app></div>').data('$injector', $injector)')
in /bower_components/angular-mocks/angular-mocks.js (line 2102)
/bower_components/angular-mocks/angular-mocks.js:2102:69
invoke@/bower_components/angular/angular.js:4443:22
/bower_components/angular/angular.js:4261:43
getService@/bower_components/angular/angular.js:4402:46
invoke@/bower_components/angular/angular.js:4434:23
/bower_components/angular/angular.js:4261:43
getService@/bower_components/angular/angular.js:4402:46
invoke@/bower_components/angular/angular.js:4434:23
/bower_components/angular/angular.js:4261:43
getService@/bower_components/angular/angular.js:4402:46
invoke@/bower_components/angular/angular.js:4434:23
/bower_components/angular/angular.js:4265:85
forEach@/bower_components/angular/angular.js:336:24
createInjector@/bower_components/angular/angular.js:4265:10
workFn@/bower_components/angular-mocks/angular-mocks.js:2922:60
# Chrome
TypeError: angular.element(...).data is not a function
at $get (/bower_components/angular-mocks/angular-mocks.js:2102:65)
at Object.invoke (/bower_components/angular/angular.js:4443:17)
at /bower_components/angular/angular.js:4261:37
at getService (/bower_components/angular/angular.js:4402:39)
at Object.invoke (/bower_components/angular/angular.js:4434:13)
at /bower_components/angular/angular.js:4261:37
at getService (/bower_components/angular/angular.js:4402:39)
at Object.invoke (/bower_components/angular/angular.js:4434:13)
at /bower_components/angular/angular.js:4261:37
at getService (/bower_components/angular/angular.js:4402:39)
Angularと一緒にjQueryを使用していることに注意してください。
これはhttps://github.com/angular/angular.js/commit/75373dd4bdae6c6035272942c69444c386f824cdに関連している可能性があり
@nikrolls
angle.element(...)。dataは関数ではありません
angular.element(...)
(Angularの前にjQueryをロードした場合はjQuery(...)
エイリアスされます)がdata
メソッドを持たないものを返すことは正しいと思いますか? それは奇妙に思えます。 Chrome DevToolsで「拒否時に中断」を有効にして、この行に到達したときに、次の式が正確に返されるものを確認してください。
angular.element
angular.element(...)
(ドットを実際にあるものに置き換えてください)...
(ドットをangular.element
ものに置き換えます)ありがとう!
Angular v1.5.1以降、同様の問題が発生しています。
should update data with success with redirect
PhantomJS 2.1.1 (Linux 0.0.0)
TypeError: undefined is not an object (evaluating '$location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search') in /project/app/bower_components/angular-route/angular-route.js (line 601)
commitRoute@/project/app/bower_components/angular-route/angular-route.js:601:82
$broadcast@/project/app/bower_components/angular/angular.js:17207:33
afterLocationChange@/project/app/bower_components/angular/angular.js:13127:28
/project/app/bower_components/angular/angular.js:13113:32
$eval@/project/app/bower_components/angular/angular.js:16884:28
$digest@/project/app/bower_components/angular/angular.js:16700:36
flush@/project/app/bower_components/angular-mocks/angular-mocks.js:1779:45
/project/app/modules/main/partners/partners.spec.js:338:31
invoke@/project/app/bower_components/angular/angular.js:4625:24
workFn@/project/app/bower_components/angular-mocks/angular-mocks.js:2933:26
Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.5.1/$rootScope/inprog?p0=%24digest (line 17242)
beginPhase@/project/app/bower_components/angular/angular.js:17242:88
$digest@/project/app/bower_components/angular/angular.js:16680:19
flush@/project/app/bower_components/angular-mocks/angular-mocks.js:1779:45
/project/app/modules/main/partners/partners.spec.js:385:39
invoke@/project/app/bower_components/angular/angular.js:4625:24
workFn@/project/app/bower_components/angular-mocks/angular-mocks.js:2933:26
inject@/project/app/bower_components/angular-mocks/angular-mocks.js:2902:46
/project/app/modules/main/partners/partners.spec.js:381:23
undefined
この場合、テストにinject()
関数が含まれていると、常にエラーがスローされます。 beforeEach
関数のspyOn($location, 'path');
が問題になる可能性があると思います。
describe('ctrl test', function () {
beforeEach(inject(function ($controller, $location) {
spyOn($location, 'path');
}));
describe('save()', function () {
it('should work', function(){
inject(function ($location) {
// some test code
});
});
});
});
@ 4kochi-問題は、実際には関数をスパイしたが、スパイの実装を提供していないことです。 つまり、 spyOn($location, path);
呼び出すと、 $location.path
メソッドがspy関数でオーバーライドされますが、そのspy関数はundefined
返します。 その後、ルーターは$location.path().search
にアクセスしようとします。これは、事実上undefined.search
と言っています。
スパイの実装を提供する必要があります:偽物またはパススルーのいずれか:
spyOn($location, 'path').andCallThrough();
spyOn($location, 'path').andCallFake(function(url) { return {...}; });
先端@petebacondarwinをありがとう私は同様の考えを持っていました。 しかし、なぜまったく同じテストコードがAngular 1.5.0で機能するのでしょうか? 私は何か見落としてますか?
inject
を使用すると、同じ問題が発生します。
beforeEach(inject(function($rootScope) {
}));
@ dagda1 、 https: //github.com/angular/angular.js/issues/14251#issuecomment -198276079に記載されている情報(およびエラーの正確なスタックトレース)を提供して
v1.5.2にアップグレードしようとした後、テストでもこの問題が発生していました。 angle-mocks.jsの2776行を次のように変更します。
angular.element.cleanData(cleanUpNodes);
に:
if (angular.element.cleanData) angular.element.cleanData(cleanUpNodes);
問題を修正します。 私たちの場合、さまざまな理由でangular.elementをスパイしようとしています。
私たちの場合、さまざまな理由でangular.elementをスパイしようとしています。
それがエラーの説明です。
angular.element
は非常に基本的な「機能」であり、内部的に大きく依存しています。 私はそれをスタブアウトすることをお勧めしません。 (それをスパイして物事を通過させることは問題ありませんが)。
ところで、コードをif (angular.element.cleanData) angular.element.cleanData(cleanUpNodes);
に変更すると、メモリリークが発生し、巨大なテストスイートでカルマがクラッシュする可能性があります。
(はい、それはすでに起こっています:smiley :)
@gkalpakに感謝し
@KeithPepin angular.element
はトリッキーな獣です。 あなたは本当にそれをスパイする必要がありますか? テストの例を挙げていただけますか?
私は同じ問題を抱えています。
いくつかのエラーメッセージを取得します:
PhantomJS 2.1.1 (Linux 0.0.0) 首页单元测试 首页内容控制器测试 调用获取数据接口 encountered a declaration exception FAILED
ReferenceError: Can't find variable: module in /client/modules/bootstrap/test/bootstrap.spec.js (line 4)
/client/modules/bootstrap/test/bootstrap.spec.js:4:23
global code@/client/modules/bootstrap/test/bootstrap.spec.js:3:9
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.041 secs / 0.001 secs)
私のテストは次のとおりです。
describe( '首页模块单元测试', function(){
var $httpBackend,
$indexFactory;
beforeEach( module( 'Datatao.bootstrap' ) );
beforeEach( inject( function( _$httpBackend_, _IndexFactory_ ){
$httpBackend = _$httpBackend_;
$indexFactory = _IndexFactory_;
}) );
describe( '首页内容控制器测试', function(){
it( '调用获取数据接口', function(){
expect( true ).toBe( true );
});
});
});
角度1.4.8とui-router0.2.15角度モック1.5.2を使用していますが、角度モックを1.5.0にダウングレードした後は問題ありません。
さらに情報が必要な場合は、 @ meをご覧ください
@terminatorheart一致しないバージョンのangularとangular-mockの使用はサポートされていません。 両方に1.5.2を使用してみましたか?
私はここでこの問題を再現しようとしましたhttps://github.com/petebacondarwin/issue-14251
しかし、 karma start
は私にとっては問題なく機能します。 プロジェクトが失敗するために、プロジェクトに他に何が必要かを提案できますか?
1.5.0から1.5.1に移行するときに、同様のエラーが発生します。
アプリケーションがブートストラップされる前に、いくつかの追加作業を行うための次のコードがあります。 現在、以下のエラーで失敗しています。
var injMods = ['ng'、 'tcpInitModule'、 'mpyInitModule'];
var initInjector = angle.injector(injMods);
var tcpMembershipSvc = initInjector.get( 'tcpMembershipSvc');
// tcpMembershipSvcプロバイダーでいくつかの作業を行います
//最後にブートストラップ
angle.bootstrap(document、['tcpMainModule']);
エラー:
キャッチされないエラー:[$
http://errors.angularjs.org/1.5.1/ $ injector / unpr?p0 =%24rootElementProvider%…%24rootElement%20%3C-%20%24location%20%3C-%20%24route%20%3C- %20%24location
ユニットテストでは、以下のエラーで失敗します。
エラー:[$ injector:modulerr ]次の理由により、モジュールngのインスタンス化に失敗しました。
TypeError: 'undefined'はオブジェクトではありません( 'Function.prototype.bind.apply'を評価しています)
インスタンス化時(c:/app/internal_packages/angular/angular.js:4640)
@mlakmalテストできる問題の実行可能なデモを作成できますか?
@petebacondarwin私は以下のplnkerを追加しました。
https://plnkr.co/edit/J32cQo4Fo9fkiRH3pF3L?p=preview
また、ユニットテストエラーがv1.5.0でも発生することに気づきました...
@mlakmalplnkrの問題はユニットテストの問題とは異なると思います。 おそらくngRouteの変更と関係があります。
ユニットテストの問題は、 Function.prototype.bind
が未定義であることが原因のようです。 PhantomJS 1.xを使用していますか?
あなたの他の問題は確かに(一種の) ngRoute
変更(5e37b2a)に関連しています-それは実際にすでに存在する問題を明らかにしています。
最小限の複製は次のとおりです: angular.injector(['ng', 'ngRoute'])
別の最小限の複製( ngRoute
)は次のようになります: angular.injector(['ng']).get('$location');
問題は、 $location
サービスが$rootElement
に依存していることです。 $rootElement
は、アプリがブートストラップされるまでAngularによって提供されません(それ以前は不明であるため)。 ブートストラップされたアプリのコンテキスト外で$location
をインスタンス化しようとすると、インジェクターは$rootElement
を取得しようとして失敗します。その時点では、 $rootElement
プロバイダーがないためです。 。
TBH、カスタムインジェクターからngRoute
をロードする理由は考えられません( @mlakmal OOC:smiley:だけでも、ユースケースの詳細を知りたいと思います)。
簡単な回避策は、 $rootElement
を提供するダミーの追加モジュールを含めることです。
angular.module('fakeRootElement', []).value('$rootElement', angular.element('<div></div>'));
var initInjector = angular.injector(['ng', 'InitModule', 'fakeRootElement']);
さて、実際の問題では、 $location
は$rootElement
を使用して、すべてのclick
イベントをインターセプトし、HTML5モードで処理します。 これを「オプションの」依存関係にすることができます(たとえば、定義されている場合にのみ$rootElement
挿入するか、ダミーの$rootElement
を提供して、ブートストラップ中に置き換えます)。
問題は、私たちがすべきかということです。
こんにちは@gkalpak 、あなたは正しいです、私たちはPhantom JS 1.9.8を使用してv2に移行しようとしていますが、ビルドエージェントで必要なノードバージョンの変更のために私たちの側で遅れています(私たちはまだノードv0.12.xにいます) 。 PhantomJSをv2にローカルでアップグレードしましたが、単体テストは良好に見えます。 PhantomJS 1の問題を修正する方法はありますか?
回避策は、インジェクターの問題を修正するためにうまく機能しました。 将来AngularJS2に移行するまで(夢を見て...)、その修正を使用して生きることができます。
ngRouteのユースケースについて:これらのCommonModuleとInitModuleでngRouteのプロバイダーを使用するサービスがいくつかあります。 そのため、単体テストの実行をサポートするために作成するときに、これらのモジュールのモジュール依存関係としてngRouteを追加する必要がありました。 これらの依存関係からそれを削除し、単体テストで必要な場合にのみngRouteを追加できると思います。
PhantomJS 1ユニットテストの問題は、カルマconfに次のポリフィルを追加した後に解決されました。 角度1.5.xのアップグレード後にこのエラーが突然発生した理由がわかりません...
@ mlakmal 、 Function.prototype.bind
使用しなかったためです。 ネイティブクラスをサポートするために必要であり、サポートされているすべてのブラウザがそれを提供するため、ここで実行します。 (PhantomJSは明示的にサポートされていないため、テストは行われていませんが、多くの人が問題なく使用しています(しばらく前までは、 ngMaterialプロジェクトを含む)。)
InitModule
ngRoute
依存について:
ngRoute
は1つのプロバイダー( $routeProvider
)のみを提供します。これはルートの登録にのみ役立ちます。 それを含む独自のインジェクターを作成する必要がある理由はまだわかりません(各インジェクターがサービスの異なるインスタンスを作成することを考えると、サービスは各インジェクターでシングルトンです)。
いくつかのヘルパーサービスを保持できるようにするためだけにInitModule
ロードしている場合は、これらのヘルパーサービスをスタンドアロンモジュール( InitModule
によって異なります)に抽出してから、そのヘルパーモジュールのみを追加のインジェクターにロードします。
@gkalpakディレクティブではngRouteの$ routeParamsを使用しています。 そのため、いくつかのモジュールに追加しました...しかし、ngRouteモジュールを仕様ファイルに個別に追加できると思います。
@mlakmal 、私のポイントは、手動で作成した追加のインジェクター( angular.injector([...])
)でngRoute
がどのように必要かわからないということでした。これは、別のインジェクター(別のサービスを使用)であるためです。インスタンス)アプリのインジェクターから。
やあみんな、数日後にこれを再び持ち出すことを残念に思う、しかし私はちょうどこれに遭遇した。
私はすべての呼び出しでangular.element
をスパイしていますが、残念ながらまだ機能していません。
spyOn( angular, 'element' ).andCallThrough();
何かご意見は?
@mattgrandeデモなしでは多くのことはできないと思います。 ;)
これは、スパイされた関数のすべてのプロパティをスパイにコピーするため、Jasmine 2.xでは問題になりません(デモを参照)。
プロパティをコピーしないJasmine1.xにはまだ問題があります(デモを参照)。
プロパティを自分でコピーすることで、これを回避できます(必要なものすべて、または必要なものだけ、たとえばcleanData
):
spyOn(angular, 'element').andCallThrough();
// Copy all properties
angular.extend(angular.element, angular.element.originalValue);
// or
// Copy `cleanData` only
angular.element.cleanData = angular.element.originalValue.cleanData;
TBH、 works as expected
/ won't fix
として閉じる傾向があります。 angular.element()
は基本的すぎて、誰かがそれをスパイしている場合は、BCに備える方がよいでしょう(またはJasmine 2:stuck_out_tongue :)
ngMock
内でこれを回避することも簡単です。たとえば、 angular.element.cleanData(...)
を次のように変更します。
var ngEl = angular.element;
(ngEl.cleanData || (ngEl.originalValue && ngEl.originalValue.cleanData) || angular.noop)(...)
しかし、明日は壊れてしまう別のテストライブラリがあるかもしれません。
だから、以来:
(a)これはJasmine 1.x(2.xではない)の問題のみです。
(b)アプリケーションコードではなくテストを中断するだけであり、
(c)修正はとても簡単です。
私は(まだ)これを「修正」しないことに傾倒しています。
@gkalpak私はあなたに同意する傾向があります。 これは「既知の問題のページ」の別のケースですよね?
@KeithPepinソリューションを使用し
if(angular.element.cleanData)
angle.element.cleanData(cleanUpNodes);
私のために働いた
この人たちに感謝します。 Jasmine 2.xにアップデートしてみます(変更はあまり多くありません)が、それが非常に大きな問題であることが判明した場合は、Keithのソリューションを使用します。
更新:私はすでにJasmine 2.1を使用していたことが判明しましたが、最新に更新しましたが、何の影響もありませんでした。
@gkalpakの「extend」メソッドを使用することになりました。 ありがとう!
@mattgrande 、どのバージョンのジャスミンにアップグレードしましたか? ジャスミンv2.4.1を使用したデモでは正常に機能しているように見えるため、機能しなかったのは不思議です:confused:
Angular-mocks1.5.2および1.5.3と同じエラー
(ジャスミン2.4.1)
ジャスミン2.4.0; Angularバージョン1.5.2
こんにちは私はPhantomJS2、カルマ、ジャスミンにも未定義の問題があります。 私はカルマとジャスミンの最新バージョンを使用しています。 私のアプリもngRouteを使用しています。
$ rootScopeと$ controllerを挿入しようとすると、問題が発生します。 モジュールの1つをモックするためにngMockを使用しています。 スコープとコントローラーは常に未定義です。 ただし、angular.moduleを使用してモジュールのみをテストすると、テストに合格します。 私はspyOnを使用していません。
エラーの可能性について何か提案はありますか?
1.4.6から1.5.3にアップグレードするときにもこの問題が発生します。
問題の実行可能なデモを提供できますか?
@petebacondarwinこれがtravisの失敗したビルドです: https : //travis-ci.org/prestonvanloon/newrelic-angular/builds/118604417
編集:これがそれを引き起こしたPRですhttps://github.com/prestonvanloon/newrelic-angular/pull/28
@prestonvanloon 、あなたの問題は、異なるバージョンのangularとangular-mocksを使用していることです。
常に一致するバージョンを使用する必要があります。
@gkalpakありがとうございます!
@prestonvanloon :使用しているangularおよびangular-mocksのバージョンを確認してください。 私は同じ問題に直面していました。 Angular-mocksバージョン1.5.5を使用していてAngularバージョンが1.4.7だったとき、同じ例外が発生しました。 Angularバージョンを1.5.5にアップグレードしたとき、エラーは発生せず、すべてのテストが正常に実行されました。
@ varun85jobsと@gkalpakに感謝します、それはまさに私の問題でした
やあみんな、Angularバージョン1.5.3とAngular-mocks 1.5.3のIonicプロジェクトがありますが、それでも同じエラーが発生します。 どうなり得るか?
こんにちは、ここで同じ問題があります。一時的な解決策として1.5.0を使用しているため、1.5.5と1.5.3で試しましたが、まだ問題があります。
KeithPepinの答えは私のためにそれを修正しました、しかし私はライブラリのコードを変更したくないです
angular.element
をスパイするための適切なユースケースはまだありません。 これがなければ、修正を進めることはできません。
使用するAngularモジュールのすべてのバージョンが一致する、実際の実行中の再現が必要です。
私はこの問題を抱えています:angular.element.parentは関数ではありません
@ kristoff2016 、これは同じ問題のようには見えません。 新しい問題を開いて、関連するコード、正確なエラーメッセージ、環境(ブラウザ、OSなど)などの詳細情報を提供してください。 ライブ複製(CodePen、Plnkrなどを使用)も高く評価されています:grin:
私の場合、問題は、古いバージョンのPhantomJSに依存する古いバージョンのkarma-phantomjs-launcher(^ 1.0.0ではなく^ 0.1.4)を使用していたことでした。 [email protected]を使用すると、正しく機能します。
+1 karma-phantomjs-launcherとphantomjsを2+にアップグレードすると、うまくいきました
これまで私のために働いた唯一のオプションは、angular / angular-mocks1.5.0にダウングレードすることでした。
これが最初に報告されてから数ヶ月が経ちましたが、実際の複製(バージョンが一致するもの)はまだここに投稿されていません!! 見えないものを直すことはできません。 :心配:
これを閉じますが、複製があればまた開いていただければ幸いです。
こんにちは@gkalpak 、時間を割いていただきありがとう:。 このplnkrに保存し
var elSelect = angular.element;
angular.element = function(id) {
try {
return elSelect.call(angular, id);
} catch(err) {
return $(id);
}
};
したがって、これはテスト時にAngularモックとAngularモックのバージョン1.5.0
で機能しますが、 1.5.1-1.5.7
では機能しません。 それがこの特定のケースなのか、それともangular.element
を使用している他のケースも壊れるかどうかはわかりません。
Thx @ vitorarins。 前に述べたように、 angular.element
ような証明書コンポーネントを上書きし、少なくともそのプロパティを保持しないことは、非常に「いたずら」なことです。 ただし、上記のangular.extend()
手法を使用するとよいでしょう。
var ngElement = angular.element;
angular.element = angular.extend(function(id) {
try {
return ngElement.call(angular, id);
} catch(err) {
return $(id);
}
}, ngElement);
@gkalpakありがとうございます! 少なくともこれが、この問題を抱えている他の人々の参考になることを願っています。 再びThxがたくさん!
こんにちは、私も同じ問題に直面しています。 しかし、角度選択を使用します。 私のコントローラーでは、このように選択を初期化しています。
angle.element( 'select')。select2();
次のようにスパイを追加しました:
var ngElement = angle.element( 'select');
angle.element = angle.extend(function(id){
{を試してください
ngElement.call(angular、id);を返します。
} catch(err){
$(id);を返します。
}
}、ngElement);
spyOn(ngElement、 'select2')。and.callFake(function(){
});
PhantomJS 2.1.1(Mac OS X 0.0.0)エラー
TypeError:読み取り専用プロパティに割り当てようとしました。
/node_modules/angular/angular.min.js:9で
私はこの投稿を完全に読み、Angular1.5.7とJasmine2.4.1を使用しました。 しかし、それでも問題は解決されていません。
@lathaMaramgantiそうではありません:
var ngElement = angular.element('select');
だが:
var ngElement = angular.element;
呼び出しではなく、元の関数を拡張するために保存する必要があります。
最も参考になるコメント
v1.5.2にアップグレードしようとした後、テストでもこの問題が発生していました。 angle-mocks.jsの2776行を次のように変更します。
angular.element.cleanData(cleanUpNodes);
に:
if (angular.element.cleanData) angular.element.cleanData(cleanUpNodes);
問題を修正します。 私たちの場合、さまざまな理由でangular.elementをスパイしようとしています。