Làm cách nào để có được ScopeConfigInterface thông qua trình quản lý đối tượng của các bài kiểm tra đơn vị trong magento 2?


8

Tôi đang cố đọc một hàng trong bài kiểm tra đơn vị của mình từ core_config_table trong cơ sở dữ liệu magento 2. Tôi biết rằng để hoàn thành công việc này vì tôi đã đọc liên kết này . Tôi phải dùng:

\Magento\Framework\App\Config\ScopeConfigInterface

xuyên qua:

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

Đây là mã của tôi:

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

Tôi có thể nhận mọi đối tượng tôi muốn bằng cách sử dụng testObject \Magento\Framework\TestFramework\Unit\Helper\ObjectManagernhưng bất cứ khi nào tôi muốn nhận\Magento\Framework\App\Config\ScopeConfigInterface

Lỗi nghiêm trọng: Không thể khởi tạo giao diện Magento \ Framework \ App \ Config \ ScopeConf igInterface trong C: \ xampp \ htdocs \ magento \ eller \ magento \ framework \ TestFramework \ Un it \ Helper \ ObjectManager.php trên dòng 162


vấn đề tương tự ở đây ....
Michel Gokan

Câu trả lời:


12

Tôi có thể sai ở đây, nhưng tôi nghĩ đối với các bài kiểm tra đơn vị bạn không phải truy xuất các giá trị từ cơ sở dữ liệu. Bạn có thể giả định rằng việc triển khai \Magento\Framework\App\Config\ScopeConfigInterfaceđược kiểm tra và hoạt động đúng. Bạn chỉ phải kiểm tra phương pháp của bạn sử dụng getValuetừ ScopeConfigInterface.
Ví dụ: nếu bạn có một phương thức như thế này:

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

bạn chỉ cần kiểm tra phương thức đó chứ không phải nếu giá trị từ db là thứ bạn cần.
và bạn có thể kiểm tra như thế này:

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

Tùy thuộc vào số lượng phụ thuộc phải được đưa vào hàm tạo, bạn thậm chí có thể không phải sử dụng ObjectManager kiểm tra đơn vị, nhưng có thể chỉ cần khởi tạo trực tiếp lớp đang kiểm tra bằng cách sử dụng new.

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

Điều này là đơn giản hơn và như vậy thích hợp hơn cho các bài kiểm tra đơn vị. Lý do duy nhất để sử dụng trình quản lý đối tượng thử nghiệm đơn vị là nếu một số lượng lớn các phụ thuộc làm cho việc chế nhạo mỗi một thủ công quá cồng kềnh.


cảm ơn câu trả lời tuyệt vời của bạn Hãy xem xét tôi muốn viết một bài kiểm tra mà mục đích của nó là khi cấu hình lõi là "Đúng" thì dữ liệu của một số sản phẩm sẽ được thay thế bằng X và khi "Sai" thì dữ liệu của một số sản phẩm sẽ được thay thế bằng Y. Nếu tôi cần phải viết một giả để kiểm tra tính đa năng này trong mô-đun của tôi, vậy thì điểm kiểm tra đơn vị là gì? Tôi muốn kiểm tra mô-đun thực tế và thực tế của mình, không phải là "giả" về chức năng của nó.
ali gh

trong trường hợp này bạn thực hiện 2 bài kiểm tra. một cho khi phương thức getValuetrả về true ->willReturn(true)và một cho khi getValuetrả về false. ->willReturn(false). Bằng cách này, bạn kiểm tra mô-đun thực tế của mình trong cả hai trường hợp, không phụ thuộc vào những gì bạn có trong db của mình.
Marius

1
@Marius là đúng nếu bạn đang viết một bài kiểm tra đơn vị sau đó bạn nên không được nói chuyện với cơ sở dữ liệu trực tiếp mà thay vào đó bạn nên chế giễu trên scopeConfigInterface và cho rằng tình trạng cơ sở dữ liệu cấu hình được thiết lập, Khi bạn bắt đầu muốn lấy dữ liệu từ cơ sở dữ liệu bạn đang bắt đầu chuyển sang kiểm tra tích hợp nơi bạn có thể gọi cơ sở dữ liệu thực tế để lấy dữ liệu và thực hiện các xác nhận trên đó.
James Cowie

@Marius Tôi đã thực hiện những gì bạn đã đề cập nhưng khi tôi khẳng định tôi sẽ luôn luôn đúng ngay cả khi $ dbValue không có giá trị thực trong cơ sở dữ liệu
ali gh

@ cao Đó là điểm. Đọc bình luận trên từ James Cowie. Anh ấy là một người có thẩm quyền trong thử nghiệm đơn vị (và tất cả các loại thử nghiệm) hơn tôi hoặc sẽ không bao giờ.
Marius

1

Tôi nghĩ bạn cần sử dụng giả cho việc này nhưng trong trường hợp của bạn, nó sẽ yêu cầu một số cấu trúc lại mô-đun của bạn, đặc biệt là sự cần thiết của một Configlớp liên quan đến mô-đun của bạn.

Bạn có thể dựa trên sự phát triển của mình app/code/Magento/Braintree/Test/Unit/Gateway/Config/ConfigTest.phpđể thực hiện một cái gì đó như thế này:

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 */
}

Vai trò của hàm willReturn trong phương thức 'testGetCountrySpecificCardTypeConfig' là gì?
ali gh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.