web-dev-qa-db-ja.com

Typescriptを使用してカスタムジャスミンマッチャーを作成する

私は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が満足する独自のマッチャーを作成するにはどうすればよいでしょうか。

12
d512

Dafの答えはほとんど私にとってはうまくいきました。私は、彼のサンプルコードと彼のファイルの名前の付け方に問題があることに気づきました。私はまた別の無関係な問題に遭遇しました。したがって、新しい答え。

  • インターフェイスファイルの名前がマッチャーファイルと同じである場合、何らかの理由で私のアプリはそれを好みません。例:foo.tsおよびfoo.d.ts。私のアプリでは、foo.tsやfoo-interface.d.tsなどである必要がありました。
  • また、インターフェイスをfoo.tsからfoo-interface.d.tsにインポートしないでください。これも気に入らないようです。

ここにカスタムマッチャーのサンプル: 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');
    })
});
5
Cameron

基本的に、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ファイルを壊したときでした。

2
daf

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モジュールとの混同を避けるため) )。

0
Sly_cardinal