私はangular2プロジェクトでジャスミンを使用していますが、テスト用のカスタムマッチャーを作成するのに問題があります。 2つの比較的複雑なオブジェクトを比較できるようにしたいと思います。私は この記事 を見つけました。これは問題を解決すると主張していますが、ジャスミンのMatchers
オブジェクトの新しいメソッドを認識しないことを示すTypeScriptエラーが発生します。関連するコードは次のとおりです。
declare module jasmine {
interface Matchers {
toBeNumeric(): void;
}
}
別の記事 同様の、しかしわずかに異なるソリューションで、同じエラーが発生します。
declare namespace jasmine {
interface Matchers {
toHaveText(expected: string): boolean;
}
}
私はこれを試しました
let m: jasmine.Matchers = expect(someSpy.someMethod).toHaveBeenCalled();
そしてこのエラーが発生しました:
タイプ「jasmine.Matchers」はタイプ「jasmine.Matchers」に割り当てることができません。この名前の2つの異なるタイプが存在しますが、それらは無関係です。
それはdeclare namespace jasmine
ステートメントは、既存の名前空間を拡張するのではなく、新しいjasmine
名前空間を作成しています。
では、TypeScriptが満足する独自のマッチャーを作成するにはどうすればよいでしょうか。
Dafの答えはほとんど私にとってはうまくいきました。私は、彼のサンプルコードと彼のファイルの名前の付け方に問題があることに気づきました。私はまた別の無関係な問題に遭遇しました。したがって、新しい答え。
ここにカスタムマッチャーのサンプル: https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/tree/master/api/src/test-helpers ここにサンプル仕様:- https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/blob/master/api/src/hello/hello.spec.ts
マッチャー-custom-matchers.ts
import MatchersUtil = jasmine.MatchersUtil;
import CustomMatcherFactories = jasmine.CustomMatcherFactories;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcher = jasmine.CustomMatcher;
import CustomMatcherResult = jasmine.CustomMatcherResult;
export const SomeCustomMatchers: CustomMatcherFactories = {
toReallyEqual: function (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]): CustomMatcher {
return {
compare: function (actual: any, expected: any): CustomMatcherResult {
if(actual === expected) {
return {
pass: true,
message: `Actual equals expected`
}
} else {
return {
pass: false,
message: `Actual does not equal expected`
}
}
}
}
}
};
インターフェースファイル--matcher-types.d.ts--をマッチャーファイルと同じ名前にすることはできません
declare namespace jasmine {
interface Matchers<T> {
toReallyEqual(expected: any, expectationFailOutput?: any): boolean;
}
}
カスタムマッチャーテスト
describe('Hello', () => {
beforeEach(() => {
jasmine.addMatchers(SomeCustomMatchers)
});
it('should allow custom matchers', () => {
expect('foo').toReallyEqual('foo');
expect('bar').not.toReallyEqual('test');
})
});
基本的に、2番目の例(「名前空間の宣言」)は、もちろん、マッチャーのロジックを別の場所に配置する方法です。
https://github.com/fluffynuts/polymer-ts-scratch/tree/5eb799f7c8d144dd8239ab2d2bcc72821327cb24/src/specs/test-utils/jasmine-matchers をご覧ください。 Jasmineのマッチャーとそれに合わせたタイピングをいくつか作成しましたが、技術的には実際のマッチャーをJavascriptで作成し、ビルドプロセスを調整するためにロジックファイルに.tsという名前を付けました。
あなたは@types/jasmine
-をインストールし、それを最新の状態に保つ必要があります。
@types/jasmine
のバージョンが異なると問題が発生する可能性があることに注意してください。具体的には、上記でリンクされたコミットは、Jasmineタイプがタイプパラメーター(つまり、Matchers<T>
)を持つMatchers
タイプを導入し、すべての.d.tsファイルを壊したときでした。
ESモジュールを使用している場合は、名前空間宣言をdeclare global
ブロックでラップする必要があります。
これは、両方のカスタムマッチャーが同じ定義にマージされた更新された例です。
declare global {
namespace jasmine {
interface Matchers {
toBeNumeric(): void;
toHaveText(expected: string): boolean;
}
}
}
宣言を分割する(または複数のファイルに分散させる)ことも可能です。
// File 1 declares this matcher
declare global {
namespace jasmine {
interface Matchers {
toBeNumeric(): void;
}
}
}
// File 2 declares this matcher
declare global {
namespace jasmine {
interface Matchers {
toHaveText(expected: string): boolean;
}
}
}
// File 3: use the custom matchers
it(function(){
expect(3).toBeNumeric();
expect(result).toHaveText('custom matcher');
});
注:これらのスニペットでは、namespace
キーワードとmodule
キーワードは同等ですが、module
は非推奨であり、namespace
が推奨されます(ESモジュールまたはCommonJSモジュールとの混同を避けるため) )。