Mageing类在Magento的其他类中实例化

时间:2018-02-19 19:55:56

标签: dependency-injection mocking phpunit magento-1.9

我试图在测试中学到更多东西,但不幸的是我必须在Magento 1.9中做到这一点。*:)

考虑以下代码(GDPR相关)......

class Vendor_Module_Helper_Data 
{
    public function __construct()
    {
        $this->config = Mage::helper('vendor_module/config');
    }

    public function anonymizeEmail(Mage_Customer_Model_Customer $customer)
    {
        return preg_replace_callback('#{([a-z_]*)}#', function ($matches) use ($customer) {
            return strtolower($customer->getData($matches[1]));
        }, $this->config->getEmailFormat());
    }
}

class Vendor_Module_Helper_Config 
{
    public function getEmailFormat()
    {
        return Mage::getStoreConfig('vendor_module/email/format));
    }
}

我正在编写一个测试,声称给定客户电子邮件的格式正确如下:

public function it_anonymizes_customer_email()
{
    $customer = Mage::getModel('customer/customer')
                    ->setEntityId(1)
                    ->setFirstname('Customer')
                    ->setLastname('Anonymous');

    $configStub = $this->createMock(Vendor_Module_Helper_Config::class);

    $configStub->method('getEmailFormat')
         ->willReturn('customer.{entity_id}@anonymo.us');

    $email = Mage::helper('vendor_module')->anonymizeEmail($customer);

    $this->assertEquals($email, 'customer.1@anonymo.us');
}

当然这不会起作用,但应该清楚我在这里尝试实现的目标......

我的问题是如何在不使用Magento缺乏的DI的情况下使这项工作做得最好。

有没有办法模拟在另一个类的构造函数中实例化(保护)的类?这是最佳做法吗?

或者这是一个有效的解决方案:

class Vendor_Module_Helper_Data 
{
    public function __construct($args)
    {
        $this->config = isset($args['config'] ? $args['config'] : Mage::helper('vendor_module/config');
    }
}

然后在测试中:

$email = Mage::helper('vendor_module', ['config' => $configStub])->anonymizeEmail($customer);

我必须将类从Helper更改为Model,因为帮助程序不接受构造函数params(我认为)。

非常感谢一些建议!

1 个答案:

答案 0 :(得分:0)

在你的情况下,我认为最好有:

class Vendor_Module_Helper_Data 
{
    public function getConfig()
    {
        return Mage::helper('vendor_module/config');
    }

    public function anonymizeEmail(Mage_Customer_Model_Customer $customer)
    {
        return preg_replace_callback('#{([a-z_]*)}#', function ($matches) use ($customer) {
            return strtolower($customer->getData($matches[1]));
        }, $this->getConfig()->getEmailFormat());
    }
}

在你的测试中:

public function it_anonymizes_customer_email()
{
    $customer = Mage::getModel('customer/customer')
                    ->setEntityId(1)
                    ->setFirstname('Customer')
                    ->setLastname('Anonymous');

    $configStub = $this->createMock(Vendor_Module_Helper_Config::class);

    $configStub->method('getEmailFormat')
         ->willReturn('customer.{entity_id}@anonymo.us');

    $helper = $this->createMock(Vendor_Module_Helper_Data::class, ['getConfig']);
    $email->expects($this->once())->method("getConfig")->willReturn($configStub);

    $this->assertEquals('customer.1@anonymo.us', $helper-> anonymizeEmail($customer));
}

所以你要创建一个方法getConfig,然后模拟它以返回你创建的另一个模拟。

另一方面,对于在Magento 1.X中进行测试,我建议使用模块EcomDev,这样可以加快测试速度,并允许您设置magento特定灯具。它暂时没有维护,但效果很好,它可以帮助你更快地编写测试。