Magento 2統合テストのモックの依存関係


8

次のシナリオを想定します。

  • 外部サービスを呼び出すクラスがあります
  • クラスはインターフェースを実装し、このインターフェースの優先実装として di.xml
  • ブロックは、コンストラクター・パラメーターとしてこのインターフェースを受け取ります
  • このブロックを使用する統合テストでMagentoリクエストをテストしたい

私は実際に外部サービスを呼び出したくないので、そのクラスをモックして、それを行うための最良の方法は何だろうと思います。

私はあなたがオンザフライでDI設定を定義できることを知っています

$objectManager->configure(
    ['preferences' => [TheInterface::class => MockClass::class]]
);

しかし、これにはMockClass自分でモッククラスを定義する必要があります。PHPUnitモックオブジェクトを使用できません。

実際のモックオブジェクトを作成するモックファクトリを作成できるため、注入されたクラスがファクトリの場合、これは問題なく動作します。

しかし、これが唯一の方法ですか、それとも私は何かを逃していますか?

更新:

提案された方法

$objectManager->addSharedInstance($mock, TheInterface::class);

最初は見栄えが良かったが設定が定義されていない場合にのみ機能した。これらは共有インスタンスよりも優先されます。

私は動的に設定を削除しようとしました:

$this->objectManager->configure(
    ['preferences' => [TheInterface::class => null]]
);

しかし、残念ながらMagentoはltrim($to, '\\')引数を呼び出し、それが空の文字列に変換します。これは結果として:

ReflectionException:クラスが存在しない

回答:


5

これには\ Magento \ TestFramework \ ObjectManager :: addSharedInstanceを使用できます。

例:

$objectManager->addSharedInstance($mock, TheInterface::class);

にまだ設定されているプリファレンスがない場合はうまく機能しますdi.xmlが、プリファレンスは共有インスタンスよりも優先されるようです。
Fabian Schmengler 2016年

2
この場合、優先クラスの共有インターフェースを追加する必要があります。例として。<preference for = "Psr \ Log \ LoggerInterface" type = "Magento \ Framework \ Logger \ Monolog" />がある場合は、共有オブジェクトを$ objectManager-> addSharedInstance($ mock、 "Magento \ Framework \ Logger \モノローグ");
KAndy

うまくいきました!
Fabian Schmengler 2016年

仮想タイプをモックしたい場合は、クラス名ではなく仮想タイプの名前を使用する必要があることに注意してください:$this->objectManager->addSharedInstance($mockedLogger, 'CustomLogger');。これは私の時間の:-P保存しているだろう知っている
Giel Berkers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.