0

I'm trying to do BDD testing on an upload method. I'm using Behat with Mink in a symfony2 project.

Now I'm able to do simple request with this client:

$this->client = $this->mink->getSession('goutte')->getDriver()->getClient();

and

$this->client->request("POST", $url, array('content-type' => 'application/json'), array(), array(), $fields);

without any issue.

How to do a request with a file? I tried this:

$file = new \Symfony\Component\HttpFoundation\File\UploadedFile($path, "video");
$fields = json_encode($table->getColumnsHash()[0]);
$this->client->request("POST", $url, array('content-type' => 'multipart/form-data'), array($file), array(), $fields);

And the error I receive is:

PHP Fatal error: Call to undefined method GuzzleHttp\Stream\Stream::addFile()

What is the mistake? Thanks!

stuzzo
  • 1,056
  • 1
  • 15
  • 36

2 Answers2

1

Ok finally I found the answer. Hope that helps someone.

To upload a file, the correct way is:

$fields = $table->getColumnsHash()[0]; //array('name' => 'test', 'surname' => 'test');
$fields["file"] = fopen($path, 'rb');
$this->client->request("POST", $url, array('Content-Type => multipart/form-data'), array(), array(), $fields);

The trick is that you must not use the fourth parameter of the Goutte request, but you have to pass all fields as body raw data.

stuzzo
  • 1,056
  • 1
  • 15
  • 36
  • What's your $table variable ? – Samuel Dauzon Dec 22 '15 at 08:04
  • It's a Behat\Gherkin\Node\TableNode object. You have an object like that when you're using this [notation](http://docs.behat.org/en/v3.0/guides/2.definitions.html#transforming-tables) – stuzzo Dec 22 '15 at 17:09
-1

I don't know about Guzzle upload but simple upload works like below. You can remove unnecessary bits.

Note: I would suggest you to keep dummy image files in project folder because if there are a lot of developers work on same project they would have exactly same folder structure so image would be accessible. I've seen some guys selecting an image from their desktop which differs from person to person so tests fail.

files_path below must point to your project directory and it should exist as e.g. /var/www/html/myproject/test/build/dummy/

behat.yml

default:
    context:
        class: Site\FrontendBundle\Features\Context\FeatureContext
        parameters:
            output_path: %behat.paths.base%/build/behat/output/
            screen_shot_path: %behat.paths.base%/build/behat/screenshot/
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://localhost/local/symfony/web/app_test.php/'
            files_path: %behat.paths.base%/build/dummy/
            javascript_session: selenium2
            browser_name: firefox
            goutte: ~
            selenium2: ~
    paths:
        features: %behat.paths.base%/src
        bootstrap: %behat.paths.features%/Context

Assuming that you have jpg.jpg under /var/www/html/myproject/test/build/dummy/ folder as below.

Example feature for upload:

Feature: Create League
  In order to upload a file
  As a user
  I should be able to select and upload a file

  @javascript
  Scenario: I can create league
    Given I am on "/"

    When I attach the file "jpg.jpg" to "league_flag"
    And I press "Submit"
    Then I should see "Succeeded."
BentCoder
  • 12,257
  • 22
  • 93
  • 165
  • HI, thanks for your answer. I am missing something. I tried to run and it says that it can't connect to host. I installed The Selenium Driver, should I install also Selenium server? Thank you for your help! – stuzzo Jan 12 '15 at 16:29
  • [See my answer here.](http://stackoverflow.com/questions/27542896/configure-behat-with-symfony2/27618212#27618212) I explained how to run Selenium. You're just going to download it into your project and run it with the command. – BentCoder Jan 12 '15 at 17:16
  • Thank you for your help, but finally I found a way to do the request as I wanted. – stuzzo Jan 16 '15 at 09:29