MageTest / MageSpec

PHPSpec for Magento
MIT License
91 stars 24 forks source link

MageSpec not load Mage::* class #99

Open jonatanrdsantos opened 9 years ago

jonatanrdsantos commented 9 years ago

Look for my environment:

Suppose that I have this model: Company/ModuleName/Model/Gateway:

class Company_ModuleName_Model_Gateway {
    public function getBaseUrl() {
        if (Mage::getStoreConfig("payment_services/payment/environment") == 'homolog'){
            $url = 'http://homolog.example.com/sendRequest.aspx';
        } else {
            $url = 'http://example.com/sendRequest.aspx';
        }

        return $url;
    }
}

And this spec Company_ModuleName_Model_GatewaySpec:

class Company_ModuleName_Model_GatewaySpec {
    function it_should_be_return_the_base_url()
    {
        $this->getBaseUrl()->shouldBeLike('http://homolog.example.com/sendRequest.aspx');
    }
}

But when run $ bin/phpspec run, I receive this error: PHP Fatal error: Class 'Mage' not found in /home/joridos/Documents/projects/magento/magento-test/.modman/magento-clearsale/app/code/community/Cammino/Clearsale/Model/Gateway.php on line 151

This is because this call: Mage::getStoreConfig("payment_services/payment/environment").

How I solve this?

shanethehat commented 9 years ago

Magespec is trying to encourage you to design your module in a way that separates your logic from the framework. Magespec is ideally suited to designing and verifying the business logic in your objects, and leaving simple stuff like pulling a config value to objects that you don't need to design.

You might choose to create an object that acts as a facade in front of the store config like so:

class Company_ModuleName_Adapter_ConfigAdapter
{
    const PAYMENT_ENV_CONFIG = 'payment_services/payment/environment';

    public function getPaymentEnvironment()
    {
        return Mage::getStoreConfig(self::PAYMENT_ENV_CONFIG);
    }
}

You can then set up the constructor of your Gateway object to create the adapter if one isn't injected:

class Company_ModuleName_Model_Gateway
{
    private $_configAdapter;

    public function __construct($services)
    {
        if (array_key_exists('config_adapter', $services)) {
            $this->_configAdapter = $services['config_adapter'];
        }
        if (!$this->_configAdapter instanceof Company_ModuleName_Adapter_ConfigAdapter) {
            $this->_configAdapter = new Company_ModuleName_Adapter_ConfigAdapter();
        }
    }

    public function getBaseUrl() {
        if ($this->_configAdapter->getPaymentEnvironment() == 'homolog'){
            return 'http://homolog.example.com/sendRequest.aspx';
        }
        return 'http://example.com/sendRequest.aspx';
    }
}

So now it's easy to use a mock of your config adapter in your specs:

class Company_ModuleName_Model_GatewaySpec
{
    function let(Company_ModuleName_Adapter_ConfigAdapter $configAdapter) {
        $this->beConstructedWith(array('config_adapter' => $configAdapter));
    }

    function it_should_be_return_the_base_url_for_homolog($configAdapter)
    {
        $configAdapter->getPaymentEnvironment()->willReturn('homolog');
        $this->getBaseUrl()->shouldReturn('http://homolog.example.com/sendRequest.aspx');
    }

    function it_should_be_return_the_standard_base_url($configAdapter)
    {
        $configAdapter->getPaymentEnvironment()->willReturn('something-else');
        $this->getBaseUrl()->shouldReturn('http://example.com/sendRequest.aspx');
    }
}
jonatanrdsantos commented 9 years ago

First, thanks for help me, I'm an newbie with spec, BDD and TDD but I try this.

First I create the Adapter folder and ConfigAdapter file in my module directory, look the tree:

└── Cammino
    └── Clearsale
        ├── Adapter
        │   └── ConfigAdapter.php
        ├── Block
        │   └── Info.php
        ├── etc
        │   ├── config.xml
        │   └── system.xml
        └── Model
            └── Gateway.php

But when I execute the tests, the result is:

Cammino_Clearsale_Model_Gateway                                                   
  14  - it should be return the base url for homolog
      collaborator does not exist : spec\Cammino_Clearsale_Adapter_ConfigAdapter

Cammino_Clearsale_Model_Gateway                                                 
  20  - it should be return the standard base url
      collaborator does not exist : spec\Cammino_Clearsale_Adapter_ConfigAdapter

Sorry if this is a easy to resolve, I'm a newbie in this world, so what I need to do?

shanethehat commented 9 years ago

Ah, sorry. That's an error on my part. You need to set those classes to the root namespace:

function let(\Company_ModuleName_Adapter_ConfigAdapter $configAdapter) {