magento 2の単体テストのオブジェクトマネージャーを使用してScopeConfigInterfaceを取得する方法


8

ユニットテストの行をmagento 2データベースのcore_config_tableから読み取ろうとしています。このリンクを読んだので、この仕事を成し遂げることを知っています 。私は使用する必要があります:

\Magento\Framework\App\Config\ScopeConfigInterface

使って:

\Magento\Framework\TestFramework\Unit\Helper\ObjectManager

これが私のコードです:

    protected function setUp()
{
    $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
    $this->scopeConfig = $objectManager->getObject('\Magento\Framework\App\Config\ScopeConfigInterface');
}

public function testgetImageCDNConfigValue()
{
    $this->scopeConfig->getValue($this->path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    if ($this->scopeConfig == null) {
        $this->assertFalse(true);
    } else {
        $this->assertTrue(true);
    }
}

testObjectを使用して必要なすべてのオブジェクトを取得できますが、取得したい\Magento\Framework\TestFramework\Unit\Helper\ObjectManagerときはいつでも\Magento\Framework\App\Config\ScopeConfigInterface

致命的なエラー:C:\ xampp \ htdocs \ magento \ vendor \ magento \ framework \ TestFramework \ Un it \ Helper \ ObjectManager.phpの162行目で、インターフェイスMagento \ Framework \ App \ Config \ ScopeConf igInterfaceをインスタンス化できません


同じ問題がここにあります....
Michel Gokan

回答:


12

私はここでは間違っているかもしれませんが、単体テストではデータベースから値を取得する必要はないと思います。の実装\Magento\Framework\App\Config\ScopeConfigInterfaceがテストされ、適切に動作していると想定できます。getValueから使用するメソッドをテストするだけScopeConfigInterfaceです。
たとえば、次のようなメソッドがあるとします。

public function getSomeConfigValue()
{
    return $this->scopeConfig->getValue('some/path/here', ScopeInterface::SCOPE_STORE)
}

そのメソッドのみをテストする必要があり、dbからの値が必要なものである場合はテストしません。
次のようにテストできます:

public function testGetSomeConfigValue()
{
    $dbValue = 'dummy_value_here';
    $scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
            ->disableOriginalConstructor()
            ->getMock();
    $scopeConfigMock->method('getValue')
            ->willReturn($dbValue);
    $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
    $myClass = $objectManager->getObject(
        \Your\Class\Name\Here::class,
        [
             'scopeConfig' => $scopeConfigMock,
             ..., //your other mocked dependencies here
        ]
    );

    $this->assertEquals($dbValue, $myClass->getSomeConfigValue());
}

コンストラクターに注入する必要のある依存関係の数によっては、単体テストObjectManagerを使用する必要がない場合もありますが、を使用してテスト中のクラスを直接インスタンス化するだけで済みますnew

$myClass = new \Your\Class\Name\Here($scopeConfigMock);

これはより簡単で、単体テストに適しています。単体テストのオブジェクトマネージャーを使用する唯一の理由は、多数の依存関係により、それぞれの依存関係を手動でモックするのが面倒すぎる場合です。


あなたの素晴らしい答えをありがとう。コア構成が "True"の場合に一部の製品のデータをXに置き換え、その "False"の場合に一部の製品のデータをYに置き換える必要があるというテストを作成することを検討してください。私のモジュールでこの機能をテストするために模擬し、ユニットテストのポイントは何ですか?機能の「モック」ではなく、実際のモジュールと実際のモジュールをテストしたい。
ali gh

この場合、2つのテストを行います。1つはメソッドgetValueがtrue ->willReturn(true)を返すとき、もう1つgetValueはfalseを返すときです。->willReturn(false)。この方法では、実際のモジュールを両方のケースでテストします。dbの内容に依存しません。
マリウス

1
あなたはその後、ユニットテストを書いている場合@Mariusは正しいはずですあなたがからデータを取得したいために起動すると、データベースに直接話をすることはないが、代わりにあなたがscopeConfigInterfaceにモックとデータベースの設定状態が設定されていることを前提としなければなりません統合テストに移行し始めたデータベース。実際のデータベースを呼び出してデータを取得し、アサーションを実行できます。
James Cowie、2016年

@マリウス私はあなたが言ったことをやったが、私が断言すると、$ dbValueがデータベースの実際の値を持っていなくても常に真になる
ali gh

@aligh。それがポイントでした。James Cowieからの上記のコメントを読んでください。彼は、ユニットテスト(およびあらゆる種類のテスト)において、私よりもはるかに権威があります。
マリウス

1

これにはモックを使用する必要があると思いますが、その場合はモジュールのリファクタリングが必要になります。特に、モジュールにConfig関連するクラスが必要です。

app/code/Magento/Braintree/Test/Unit/Gateway/Config/ConfigTest.php次のようなものを実装するに基づいて開発を行うことができます。

namespace Magento\Braintree\Test\Unit\Gateway\Config;

use Magento\Braintree\Gateway\Config\Config;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;

/**
 * Class ConfigTest
 */
class ConfigTest extends \PHPUnit_Framework_TestCase
{
    const METHOD_CODE = 'braintree';

    /**
     * @var Config
     */
    private $model;

    /**
     * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    private $scopeConfigMock;

    protected function setUp()
    {
        $this->scopeConfigMock = $this->getMock(ScopeConfigInterface::class);

        $this->model = new Config($this->scopeConfigMock, self::METHOD_CODE);
    }

    /**
     * @param string $value
     * @param array $expected
     * @dataProvider getCountrySpecificCardTypeConfigDataProvider
     */
    public function testGetCountrySpecificCardTypeConfig($value, $expected)
    {
        $this->scopeConfigMock->expects(static::once())
            ->method('getValue')
            ->with($this->getPath(Config::KEY_COUNTRY_CREDIT_CARD), ScopeInterface::SCOPE_STORE, null)
            ->willReturn($value);

        static::assertEquals(
            $expected,
            $this->model->getCountrySpecificCardTypeConfig()
        );
    }

    /* skipped code */
}

「testGetCountrySpecificCardTypeConfig」メソッドのwillReturn関数の役割は何ですか?
ali gh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.