Exziled
Exziled

Reputation: 493

PHP unit test converting object to array

I'm trying to finalize a unit test but it's failing when I get something from the session and then cast it into an array.

What I'm doing:

public function formatAddress($address) {
        if(empty($address)) {
            $full_address = craft()->httpSession->get('address');
            $full_address = (array) $full_address;
            return $formatted_address = array(
                "address1" => $full_address['street'],
                "city" => $full_address['city'],
                "state" => $full_address['state'],
            );
        } else {
            return $address;
        }
    }



$formatted_address = $this->formatAddress($user['address']);

How it's coming back from the session:

stdClass Object
(
    [city] => Warsaw
    [county] => Hancock
    [id] => 110458115f8a45849a31df1d9144aa62
    [latitude] => 40.27917
    [longitude] => -91.30012
    [state] => IL
    [street] => 1091 E County Road 550
    [zip] => 62379-3212
)

So I take this session variable, typecast it to an array then take those array properties and assign them to keys in another array.

However, when running my unit test it's telling me that there's an undefined index "street" on the 'address1" => $full_address['street'], line?

The function works perfect in my dev, but the unit test is not liking it for some reason.

Unit test:

$mocked_address = array(
            "address1" => "109 some street",
            "city" => "some city",
            "state" => "AZ",
            "zip" => "99955"
        );

          $this->httpSession
            ->shouldReceive('get')
            ->with('address')
            ->andReturn($mocked_address);

Upvotes: 1

Views: 651

Answers (1)

helmbert
helmbert

Reputation: 37994

Have a closer look at your $mocked_address object in your test case. You're trying to access the key street that does not exist in that array. This causes a PHP notice. I assume that your development environment is configured to hide such notices via PHP's error_reporting setting. However, PHPUnit is a lot more strict and does not like PHP errors (even tiny ones, like notices) at all.

You have two options:

  1. Just fix your error. If it is possible that an address does not contain a street, check if it is set before accessing it:

    return $formatted_address = array(
        "address1" => isset($full_address['street']) ? $full_address['street'] : NULL,
        "city" => $full_address['city'],
        "state" => $full_address['state'],
    );
    
  2. Configure PHPUnit to not convert PHP notices into exceptions. This can be done by creating a XML configuration file for PHPUnit and setting the convertNoticesToExceptions attribute to false:

    <phpunit
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
        convertNoticesToExceptions="true">
        <!-- ... -->
    </phpunit>
    

As a general recommendation, I suggest to always enable PHP notices in your development environment. I've seen quite a lot of bugs that could have easily been prevented by looking at PHP notices.

Upvotes: 2

Related Questions