Skip to content

Bug in /src/Codeception/Step.php in getArguments() method #30

@tiger-seo

Description

@tiger-seo

Привет.
Хотел заюзать метод seeResponseContainsJson в REST модуле, но столкнулся с багом. Условие задаю как в доке:

    $I = new ApiGuy($scenario);
    $I->wantTo('fail to create a new user by API');
    $params = [
        'email'       => 'some@email.com',
        'password'    => 'qwertyui',
        'language_id' => '1'
    ];
    $I->sendPOST('/1/user/create', $params);
    $I->seeResponseIsJson();
    $I->seeResponseCodeIs(412);
    $I->seeResponseContainsJson(['error' => 'true']);
    $I->seeResponseContainsJson(['code' => 412]);

Но результат:

There was 1 error:                                                         

Couldn't fail to create a new user by api (QwertyCept.php)



  [ErrorException]                                                         
  8 Array to string conversion                                             

Длительная и глубокая отладка привела меня к:

    public function beforeStep(\Codeception\Event\Step $e) {
        $this->logger->info($e->getStep()->getHumanizedAction());
    }

в файле /pear/pear/Codeception/src/Codeception/Subscriber/Logger.php
а затем к getArguments в /pear/pear/Codeception/src/Codeception/Step.php

    /**
     * Returns this step's arguments.
     *
     * @param  boolean $asString
     * @return array|string
     */
    public function getArguments($asString = FALSE)
    {
        if (!$asString) {
            return $this->arguments;
        } else {
            $arguments = $this->arguments;

            foreach ($arguments as $k => $argument) {
                if (!is_string($argument) and is_callable($argument, true)) {
                    $arguments[$k] = 'lambda function';
                    continue;
                }
                if (is_object($argument)) {
                    if (method_exists($argument, '__toString')) {
                        $arguments[$k] = $argument->__toString();
                    } elseif (isset($argument->__mocked)) {
                        $arguments[$k] = $this->formatClassName($argument->__mocked);
                    } else {
                        $arguments[$k] = $this->formatClassName(get_class($argument));
                    }
                    continue;
                }
                // if (settype($argument, 'string') === false) throw new \InvalidArgumentException('Argument can\'t be converted to string or serialized');
            }

            switch (count($arguments)) {
                case 0:
                    return '';
                case 1:
                    return '"' . $arguments[0] . '"';
                default:

                    return stripcslashes(json_encode($arguments));

            }
        }
    }

Возможное решение (мне помогло) - такой код:

            switch (count($arguments)) {
                case 0:
                    return '';
                case 1:
                    if (is_array($arguments[0])) {
                        $arguments[0] = stripcslashes(json_encode($arguments[0]));
                    }
                    return '"' . $arguments[0] . '"';
                default:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions