Bagaimana cara mendapatkan ScopeConfigInterface melalui manajer objek pengujian unit di magento 2?

8

Saya mencoba membaca baris dalam pengujian unit saya dari core_config_table di database Magento 2. Saya tahu itu untuk menyelesaikan pekerjaan ini karena saya telah membaca tautan ini . Saya harus menggunakan:

\Magento\Framework\App\Config\ScopeConfigInterface

melalui:

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

Ini kode saya:

    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);
    }
}

Saya bisa mendapatkan setiap objek yang saya inginkan dengan menggunakan testObject \Magento\Framework\TestFramework\Unit\Helper\ObjectManagertetapi setiap kali saya ingin mendapatkannya\Magento\Framework\App\Config\ScopeConfigInterface

Kesalahan fatal: Tidak dapat membuat instance antarmuka Magento \ Framework \ App \ Config \ ScopeConf igInterface di C: \ xampp \ htdocs \ magento \ vendor \ magento \ framework \ TestFramework \ Un it \ Helper \ ObjectManager.php on line 162

ali gh
sumber
masalah yang sama di sini ....
Michel Gokan

Jawaban:

12

Saya mungkin salah di sini, tapi saya pikir untuk pengujian unit Anda tidak harus mengambil nilai dari basis data. Anda dapat mengasumsikan bahwa implementasi \Magento\Framework\App\Config\ScopeConfigInterfacediuji dan bekerja dengan benar. Anda hanya perlu menguji metode yang digunakan getValuedari ScopeConfigInterface.
Misalnya, jika Anda memiliki metode seperti ini:

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

Anda perlu menguji metode itu saja dan tidak jika nilai dari db adalah yang Anda butuhkan.
dan Anda dapat mengujinya seperti ini:

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());
}

Bergantung pada jumlah dependensi yang harus disuntikkan ke dalam konstruktor, Anda mungkin bahkan tidak harus menggunakan ObjectManager uji unit, tetapi cukup instantiate kelas yang diuji secara langsung menggunakan new.

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

Ini lebih sederhana dan karena itu lebih disukai untuk pengujian unit. Satu-satunya alasan untuk menggunakan manajer objek tes unit adalah jika sejumlah besar dependensi membuat mengejek masing-masing secara manual terlalu rumit.

Marius
sumber
terima kasih atas jawaban Anda Pertimbangkan saya ingin menulis tes yang tujuannya adalah bahwa ketika konfigurasi inti "Benar" maka beberapa data produk harus diganti dengan X dan ketika "Salah" maka beberapa data produk harus diganti dengan Y. Jika saya perlu menulis mengejek untuk menguji fungsi ini di modul saya, lalu apa gunanya pengujian unit? Saya ingin menguji modul saya yang sebenarnya dan nyata, bukan "tiruan" dari fungsinya.
ali gh
dalam hal ini Anda membuat 2 tes. satu untuk ketika metode getValuemengembalikan true ->willReturn(true)dan satu untuk ketika getValuemengembalikan false. ->willReturn(false). Dengan cara ini Anda menguji modul Anda yang sebenarnya dalam kedua kasus, tidak tergantung pada apa yang Anda miliki di db.
Marius
1
@Marius benar jika Anda menulis tes unit maka Anda harus tidak berbicara ke database secara langsung namun Anda harus mengejek pada scopeConfigInterface dan menganggap bahwa negara database konfigurasi diatur, Ketika Anda mulai ingin mendapatkan data dari database yang Anda mulai beralih ke tes integrasi di mana Anda kemudian dapat memanggil database yang sebenarnya untuk mendapatkan data dan melakukan pernyataan di atasnya.
James Cowie
@Marius Saya telah melakukan apa yang Anda sebutkan, tetapi ketika saya tegaskan saya akan selalu menjadi kenyataan bahkan jika $ dbValue tidak memiliki nilai aktual dalam basis data
ali gh
@ aligh. Itulah intinya. Baca komentar di atas dari James Cowie. Dia jauh lebih memiliki otoritas dalam pengujian unit (dan semua jenis pengujian) daripada saya atau yang pernah ada.
Marius
1

Saya rasa Anda perlu menggunakan tiruan untuk ini tetapi dalam kasus Anda itu akan memerlukan beberapa refactoring modul Anda, terutama kebutuhan Configkelas yang terkait dengan modul Anda.

Anda dapat mendasarkan pengembangan Anda pada app/code/Magento/Braintree/Test/Unit/Gateway/Config/ConfigTest.phpyang mengimplementasikan sesuatu seperti ini:

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 */
}
Raphael di Digital Pianism
sumber
Apa peran fungsi willReturn dalam metode 'testGetCountrySpecificCardTypeConfig'?
ali gh