contexts icon indicating copy to clipboard operation
contexts copied to clipboard

grab a field in a response and then use for a request

Open coulon-xyz opened this issue 8 years ago • 5 comments

Hi,

I would like to test end-to-end functionality of my API. Is there any one i can grab the ID of an an entity i've just created, and then use this ID to patch this entity. POST /location grab location id in node data[0].id and then use this id to test GET /location/{{id}}

I can do that easily with postman's runner but it's not as good as behatch to do functional testing...

anyone ?

Julien

coulon-xyz avatar Mar 24 '17 10:03 coulon-xyz

Intuitively, I’ll create a custom context based on Behatch\Contex\RestContext with a method calls getTheLastCreatedLocation and use $this->request->getContent() to retreive the last response content.

sanpii avatar Mar 24 '17 11:03 sanpii

That's more or less what i've got. class CustomJsonContext extends JsonContext { var $portfolioId;

/** * @Then I grab the value of the portfolioId */ public function iGrabTheValueOfThePortfolioid() { $json = $this->getJson(); $this->portfolioId = $this->inspector->evaluate($json, $node); }

} }

But now, I would like to be able to use this $portfolioId in an CustomRestContext class. I could write the variable in a file and read it, but that's a bit ugly. There is probably a easy solution to this. I'm not a very good PHP dev...

coulon-xyz avatar Mar 24 '17 12:03 coulon-xyz

class FeatureContext extends \Behatch\Context\RestContext
{
    public function iGrabTheValueOfThePortfolioid()
    {
        $json = json_decode($this->request->getContent());
        $id = $json->data[0]->id;
        $location = $this->iSendARequestTo('GET', "/location/$id");
    }
}

sanpii avatar Mar 24 '17 13:03 sanpii

I'm not sure this is working anymore. When I try to implement a context that extends RestContext I have this error :

Step "I send a :method request to :url" is already defined in

I just tried to acces to another context, using this method : http://behat.org/en/latest/cookbooks/accessing_contexts_from_each_other.html

But as $request is protected in BehatchContext it's impossible to get it.

brice avatar Sep 09 '19 09:09 brice

Hi here is my solution:

<?php

declare(strict_types=1);

namespace Cnty\CommonBundle\TestHelper\Behat;

use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behatch\Context\JsonContext;
use Behatch\HttpCall\HttpCallResultPool;

class CntyJsonContext extends JsonContext
{
    /**
     * @var \Behatch\Context\RestContext
     */
    private $restContext;

    public function __construct(HttpCallResultPool $httpCallResultPool, $evaluationMode = 'javascript')
    {
        parent::__construct($httpCallResultPool, $evaluationMode);
    }

    /** @BeforeScenario */
    public function gatherContexts(BeforeScenarioScope $scope)
    {
        $environment = $scope->getEnvironment();
        try {
            $this->restContext = $environment->getContext('Behatch\Context\RestContext');
        } catch (\Exception $e) {
            // no such context, probably not registered in behat.yml
        }
    }

    /**
     * @When /^I send a "([^"]*)" project request to "([^"]*)" where id is "([^"]*)" from last request$/
     */
    public function iSendARequestWithIdFormLastRequest($method, $url, $node)
    {
        $json      = $this->getJson();
        $id        = $this->inspector->evaluate($json, $node);
        $urlWithId = str_replace('$id', $id, $url);
        $this->restContext->iAddHeaderEqualTo('Accept', 'application/ld+json');
        $this->restContext->iAddHeaderEqualTo('Content-Type', 'application/ld+json');
        $this->restContext->iSendARequestTo($method, $urlWithId);
    }
}

Usage:

    Given I am authenticated as "[email protected]"
    When I send a "GET" project request to "/api/reviews/aa329a49-04ca-4bc7-a4de-915b30f3a18e/corrections"
    Then the response status code should be 200
    Then the JSON node "hydra:member" should have 1 element
    And the JSON node "hydra:member[0].review" should be equal to "/api/reviews/aa329a49-04ca-4bc7-a4de-915b30f3a18e"
    Given I am authenticated as "[email protected]"
    When I send a "GET" project request to "/api/corrections/$id/correction_items" where id is "hydra:member[0].id" from last request
    Then the response status code should be 200
    And print last JSON response
    And the JSON node "hydra:member" should have 1 element
    And the JSON node "hydra:member[0].comments" should have 1 element
    And the JSON node "hydra:member[0].comments[0].comment" should be equal to "this is a test"
    And the JSON node "hydra:member[0].tag.id" should be equal to "9948f0f3-2afd-4e82-b07d-138ad26faaa8"

Nightbr avatar Jul 17 '20 09:07 Nightbr