3

Following is the Unit Test error that I get

Expectation failed for method name is equal to when invoked zero or more times Parameter 0 for invocation Magento\Framework\App\Config\ScopeConfigInterface::getValue('module/general/base_url', 'store', null) does not match expected value. 'custom/general/base_url' does not match expected type "array".

My test code is as below

<?php
namespace Custom\Module\Test\Unit\Helper;

class ConfigTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Custom\Module\Helper\Config
     */
    protected $configHelper;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * Sets up the fixture, for example, open a network connection.
     * This method is called before a test is executed.
     *
     */
    protected function setUp()
    {
        $methods = array_merge(
            get_class_methods(\Magento\Framework\App\Config\ScopeConfigInterface::class)
        );
        $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
            ->setMethods($methods)
            ->disableOriginalConstructor()
            ->getMock();

        $this->scopeConfig->method('getValue')
            ->with([
                'module/general/base_url',
                'module/general/user',
                'module/general/api_user',
                'module/general/api_password'
            ])
            ->willReturnMap([
                ['base_url', 'http://domain.com/'],
                ['user', 'User'],
                ['api_user', 'customapi@domain.com'],
                ['api_password', 'ynY6rdZ3EDd3']
            ]);

        $context = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->configHelper = new \Custom\Module\Helper\Config($context, $this->storeManager, $this->scopeConfig);
    }

    public function testBaseUrl()
    {
        $defaultValue = 'http://domain.com/';
        $this->assertEquals($defaultValue, $this->configHelper->getUser());
    }

    public function testConfiguratorScriptUrl()
    {
        $defaultValue = 'http://domain.com/Theme/User/Content/Scripts/Configurator/configurator.js';
        $this->assertEquals($defaultValue, $this->configHelper->getConfiguratorScriptUrl());
    }
}

I have gone through many other examples on the website with single stud method and willReturn value and that works. But I wanted to test multiple scope config values and based on my code my can't get the it working. I am not using any many methods here, both getBaseUrl() and getConfiguratorScriptUrl() are actual functions that I use to retrieve the values using helper.

Please guys let me know if you need any more details or any other part of the code that you think may be linked with it.

1
    $this->scopeConfig->method('getValue')
        ->with([
            'module/general/base_url',
            'module/general/user',
            'module/general/api_user',
            'module/general/api_password'
        ])
        ->willReturnMap([
            ['base_url', 'http://domain.com/'],
            ['user', 'User'],
            ['api_user', 'customapi@domain.com'],
            ['api_password', 'ynY6rdZ3EDd3']
        ]);

Here you tell the mock that getValue is expected to be called with the parameter

[
    'module/general/base_url',
    'module/general/user',
    'module/general/api_user',
    'module/general/api_password'
]

(yes, that's one array)

So when comparing it to the actual parameter 'custom/general/base_url' it already fails at the type check. This is what the error message tells you:

'custom/general/base_url' does not match expected type "array".

If the order of calls is important or will not change, you can use withConsecutive instead of with:

    $this->scopeConfig->method('getValue')
        ->withConsecutive(
            ['module/general/base_url'],
            ['module/general/user'],
            ['module/general/api_user'],
            ['module/general/api_password']
        )
        ->willReturnMap([
            ['base_url', 'http://domain.com/'],
            ['user', 'User'],
            ['api_user', 'customapi@domain.com'],
            ['api_password', 'ynY6rdZ3EDd3']
        ]);

Note that withConsecutive takes a variable amount of arguments and each is an array with the expected parameters for the respective method call.


But I would recommend to remove the parameter assertion altogether. The scope config object is a stub that should return certain values. You do not actually want to test which methods are called on it and in which order.

This leaves us with this simple solution:

$this->scopeConfig->method('getValue')
    ->willReturnMap([
        ['module/general/base_url', ScopeInterface::SCOPE_STORE, null, 'http://domain.com/'],
        ['module/general/user', ScopeInterface::SCOPE_STORE, null, 'User'],
        ['module/general/api_user', ScopeInterface::SCOPE_STORE, null, 'customapi@domain.com'],
        ['module/general/api_password', ScopeInterface::SCOPE_STORE, null, 'ynY6rdZ3EDd3']
    ]);
  • Hi @fabian I tried using withConsecutive and without that as you have shown but it doesn't work for me. The good thing is now I don't get the error, but I don't get any of the values that are mapped too. – VK Ranjith Feb 8 '17 at 10:15
  • @VKRanjith then there is something wrong with your return value map. I think it is because ScopeConfigInterface::getValue() has optional arguments. You cannot leave those out in the map, you have to specify the default values instead. Ex: ['module/general/base_url', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null, 'http://domain.com/'] – Fabian Schmengler Feb 8 '17 at 10:47
  • I will try it and let you know the result. – VK Ranjith Feb 9 '17 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.