Sinon: ESMのデフォルトのエクスポートをスパイすると失敗する/不可解にブロックされる

作成日 2020年05月02日  ·  21コメント  ·  ソース: sinonjs/sinon

バグを説明する
以前は、 import * as foo from 'someModule' + spy(foo, 'default')組み合わせで問題なく機能していました(そして、この手動スローによって明示的にブロックされるようになりました。

予想される行動
デフォルトのエクスポートをスパイするSinon。

コンテキスト(次の情報を入力してください):

  • ライブラリバージョン:9.0.2

追加のコンテキスト
これはTypeError: Cannot assign to read only propertyを避けるためだと思います

ただし、これは古いskool __defineGetter__を使用して回避できます。

最も参考になるコメント

@mroderickコメントが気に入らない場合は、無視してください。 他のユーザーに役立つコメントを積極的に削除しても、まったく役に立ちません。 コメントを削除すると、同じようなユーザーが何度も何度もコメントしてくることになり、スレッドがロックされてしまうとしましょう。

編集:非常に見つけやすい「購読解除」ボタンを使用することもできます。 :)

私はこのプロジェクトのメンテナであり、すべてのコメントを読んでみます。

コメントを無視したり、問題の購読を解除したりすることはできません。なぜなら、人々は定められたルールに従わず、提供されたガイダンスを無視し、自分の目的のために元の問題を乗っ取ることにしたからです。 丁寧で、巧妙で、効率的な方法で問題を解決しようとするのは私の責任です。 ハイジャックの問題により、コミュニティをサポートするのが必要以上に難しくなります。

私があなたと他のコミュニティを助けるのを手伝ってください。

全てのコメント21件

その古い問題には実際には__defineGetter__についての言及はなく、Object.definePropertyだけであり、実際のECMAScriptモジュールではなく、トランスパイルされたWebpackモジュールのみを処理します。 それが機能しないと言っているわけではありませんが😄

インポートされたESモジュールの(デフォルト以外の)エクスポートを上書きできる、まっすぐなバニラJavaScriptの例を投稿できますか? これをテストするには、2つのファイルsome-module.mjsfile-that-overwrites.mjsが必要です。また、 import構文を有効にするには、ノードの.mjs拡張子が必要です。

このテストスイートは、 Sinonの現在の動作を文書化します。

ここでは、FYIスタブは[email protected]+では機能しません

@ fatso83その古い問題は確かにそうではありません(しかし、私はそれが起こったとは言いませんでした😜)。

つまり、後でコードObject.defineProperty(object, property, methodDesc)TypeError: Cannot assign to read only property 'default'失敗するため、SinonはESMを検出するときにエラーをスローします。 ただし、 __defineGetter__は失敗しません。

object.__defineGetter__(property, methodDesc.value);

Buuuut、Sinonコードを変更して実行しようとすると、 __defineGetter__未定義のエラーが発生しました(おそらく厳密モードか何か?)。

そのため、プロパティをオーバーライドするのではなく、オブジェクトを(新しい値で)再作成するなど、おそらく別の方法を考えています。 より複雑ですが、少なくとも実行可能です。

ここでは、FYIスタブは[email protected]+では機能しません

ここで同じ問題が最後に機能したバージョン3.8.3

@zorji@aelbore :なぜこのスレッドに投稿しているのかはサポートされておらず、そのように言ったことはあり

そのため、プロパティをオーバーライドするのではなく、オブジェクトを(新しい値で)再作成するなど、おそらく別の方法を考えています。 より複雑ですが、少なくとも実行可能です。

それは...ですか? ESモジュールは、実行時にバインドされる静的機能であるAFAIKであり、変更することはできません。

インポートされた機能はファイルで利用でき、エクスポートされた機能の読み取り専用ビューです。 インポートされた変数を変更することはできませんが、constと同様のプロパティを変更することはできます。 さらに、これらの機能はライブバインディングとしてインポートされます。つまり、constとは異なり、バインディングを変更できない場合でも、値が変更される可能性があります。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

これでどこにでも行けるか楽しみですが、あなた(または誰か!)がそうしたらびっくりします。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

悪いボット。 この愚かなことをオフにすることはできますか?

@OmgImAlexisこの問題を開いたままにする理由があると思いますか?

皆さん、問題を適切に保ち、元の投稿で言及されていることだけを話し合うようにしてください。

同じ問題で直交するトピックをナビゲートする必要なしに、メンテナが無料のソフトウェアをサポートするために私たちの無給の無料の時間を費やすのは十分に挑戦的です。

Sinon(JavaScriptツール)がTypeScriptコミュニティでも役立つことを嬉しく思います。 ただし、 @ fatso83が言ったように、 はサポートしていません

この号のTypeScriptに関するトピック外のコメントは削除されます。

この号のTypeScriptに関するトピック外のコメントは削除されます。

@mroderickコメントが気に入らない場合は、無視してください。 他のユーザーに役立つコメントを積極的に削除しても、まったく役に立ちません。 コメントを削除すると、同じようなユーザーが何度も何度もコメントしてくることになり、スレッドがロックされてしまうとしましょう。

編集:非常に見つけやすい「購読解除」ボタンを使用することもできます。 :)

申し訳ありませんが、私は仕事で非常に忙しくなりました。 数週間後に見てみます。 いくつかのライブラリがこれを達成しているので、それは可能でなければなりません😁

@mroderickコメントが気に入らない場合は、無視してください。 他のユーザーに役立つコメントを積極的に削除しても、まったく役に立ちません。 コメントを削除すると、同じようなユーザーが何度も何度もコメントしてくることになり、スレッドがロックされてしまうとしましょう。

編集:非常に見つけやすい「購読解除」ボタンを使用することもできます。 :)

私はこのプロジェクトのメンテナであり、すべてのコメントを読んでみます。

コメントを無視したり、問題の購読を解除したりすることはできません。なぜなら、人々は定められたルールに従わず、提供されたガイダンスを無視し、自分の目的のために元の問題を乗っ取ることにしたからです。 丁寧で、巧妙で、効率的な方法で問題を解決しようとするのは私の責任です。 ハイジャックの問題により、コミュニティをサポートするのが必要以上に難しくなります。

私があなたと他のコミュニティを助けるのを手伝ってください。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

悪いボット。

@ jshado1この問題は開いたままにしておくべきだと思いますか?

@ jshado1は、これは正常に機能していたと言っているようですが、これがバニラのトランスパイルされていないjavascriptで機能したことはないと思います。 すべきではないからです。 モジュールをエミュレートするだけで、ランタイム(モジュールはどれか)で実際には読み取り専用オブジェクトを作成しないため、Babel / Webpackなどを使用してモジュールをトランスパイルするときに機能します。 throw句は私が追加したものです。これは、変更できないものを変更しようとしたときに、少し後でスローするためです。 ただし、 esmなどのランタイム/モジュールローダーは、フィールドを少し変更します。

動作が間違っていると思われる場合は、 node_modules/sinon/lib/sinon/spy.js編集し、throws句を削除して、レポートを返すことをお勧めします。 何恨みっこない。 約束:ユニコーン::レインボー:

@RyanCavanaughを引用

commonjsをターゲットにしているが、ESモジュールのインポート/エクスポートを記述している場合でも、TSはESモジュールの動作を提供しようとします。

このコードは、読み取り専用プロパティを( sinon.stubを介して間接的に)変更しようとしているため、事実上合法的なESではありません( import * as nameインポートされたもののプロパティは変更できません)。 それは決してうまくいかなかったはずです。

それは基本的に私が言っていることです。 最後に、この結果は、トランスパイルステップを使用するユーザー、トランスパイラーがそのステップをどのように実行するかなどに完全に依存しているためです。ESM仕様にある程度準拠した結果を作成しようとすると、「機能しないはずです」 ESモジュールのエクスポートは不変です(もちろん、それらのエクスポートによってバインドされる実際のオブジェクトではありません)。

@mroderick @ fatso83申し訳ありませんが、私はその非難されています。 数か月が経ちましたが、メモリが役立つ場合は、それが機能したことを確認するために、当時は_非常に_基本的な(そしてダーティなAF)動作例がありました(しかし、実際には_おそらく_そうではないはずです)。 しかし、私はそれがbeccccauuseに行く方法ではないと思います:私はemsローダーを介してこれを行う公式の方法があると信じています//github.com/nodejs/node/blob/master/doc/api/esm .md#loaders

これらは現在不安定であるため(すぐに変更されることが明示的に述べられています)、安定するまで延期する可能性があります。 しかし、一度やったら、それが進むべき道だと思います。

更新:これは現在nodejs / node#36396で議論されています。

このコメントでの私の提案は、これを非常に簡単にするだろうと思います。 ユーザーは手動でマップを提供でき、esmローダーはそれを使用して次のように置き換えることができます。

// const mocksMap = { 'serviceA.js': 'serviceA.mock.js' };

const mock = mocksMap[importPath]; // note: it's not called `importPath` in the loader hooks
if (mock) // …

および/または、esmローダーはファイル名に基づいてモックマッチを探すことができます(クイックアンドダーティの例):

const ext = path.ext(importPath);
const filename = path.basename(importPath, ext);
const mockFile = await import(`${filename}.mock${ext}`);

if (mockFile) // …

@ jshado1そのリンクを提供していただきありがとうございます。 リンクされた問題は、基本的に、_link level_で依存関係を置き換える問題を処理する標準化された方法を見つけようとすることです。これは、rewireやproxyquireなどのツールが行うことと似ています(ホームページのこのハウツーで説明し

このページは役に立ちましたか?
0 / 5 - 0 評価