Home  >  Q&A  >  body text

How to mock Mage::getSingleton('checkout/cart') in php-unit?

I have this foo() method and I need to add unit test case for this method testFoo() in Magento. But Mage::getSingleton('checkout/cart') cannot be simulated.

Source method

public function foo()
{
    return Mage::getSingleton('checkout/cart')->getQuote()->getFunctionName();
}

Test function

public function testFoo(): void
{
    //$this->className :: Project_Catalog_Helper_Test
    $expected = 'string';
    $this->className->method('getSingleton')->willReturn($this->cart);
    $this->cart->method('getQuote')->willReturn($this->cart);
    $this->cart->method('getFunctionName')->willReturn('string');
    $this->assertEquals(
        $this->className->foo(),
        $expected
    );
}

When I run, php-unit receives this error log.

MacBook-Pro % ./vendor/bin/phpunit tests/src/app/code/local/project/Catalog/Helper/OrderTest.php
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.11
Configuration: /project_path/phpunit.xml.dist

E                                                                   1 / 1 (100%)

Time: 150 ms, Memory: 8.00MB

There was 1 error:

1) Project_Catalog_Helper_Test::testFoo
Error: Call to a member function getCode() on bool

/project_path/app/code/core/Mage/Customer/Model/Session.php:103
/project_path/app/code/core/Mage/Core/Model/Config.php:1394
/project_path/app/Mage.php:517
/project_path/app/Mage.php:531
/project_path/app/code/community/Checkout/Model/Cart.php:20
/project_path/app/code/local/project/Catalog/Helper/Order.php:21
/project_path/tests/src/app/code/local/project/Catalog/Helper/OrderTest.php:100
/project_path/vendor/phpunit/phpunit/phpunit:53

Need some solutions, how to simulate Mage::getSingleton('checkout/cart').

Note: I cannot change the main method because it is legacy code. Just add unit test cases.

P粉244730625P粉244730625172 days ago406

reply all(1)I'll reply

  • P粉588152636

    P粉5881526362024-04-04 11:05:45

    You cannot mock Mage::getSingleton('checkout/cart') because it is a static function in the global namespace.

    However, you can inject the simulation using metaprogramming by injecting the checkout card simulation. Then restore the original singleton at that location.

    Compare to existing Q&A inherited from EComDev Testsuite, which should have more pointers on how to handle internal structures using PHP Reflection.

    reply
    0
  • Cancelreply