I have a form where a user has to select a gender. This is a radio with two options - male and female. As a part of my test I want to see how the website reacts when something other than male or female is submitted. As the HTML of the page can easily be changed to anything on the user side, I want to imitate this behaviour in my scenario. However, browserKit that comes with Mink is too smart - it recognises it's dealing with a radio and helpfully throws me an exception if I try to change the value to something that is not expected.
Input "application[sex]" cannot take "iDontKnow" as a value (possible values: male, female). (InvalidArgumentException)
Scenario Outline: Submit form with various data
Given I am on homepage
And I fill in "application[name]" with "<name>"
And I fill in "application[sex]" with "<sex>"
And I fill in "application[age]" with "<age>"
And I fill in "application[country]" with "<country>"
And I press "Save"
Then I should see "<expectedText>"
Examples:
| name | sex | age | country | expectedText |
| Test user | iDontKnow | 30 | United Kingdom | Invalid sex |
| Test user | male | 30 | NonExistantCountry | Invalid country |
How do I submit iDontKnow as a value to
<div id="application_sex">
<input type="radio" id="application_sex_0" name="application[sex]" required="required" value="male">
<label for="application_sex_0" class="required">male</label>
<input type="radio" id="application_sex_1" name="application[sex]" required="required" value="female">
<label for="application_sex_1" class="required">female</label>
</div>
... if it is even possible?
Looking at the ChoiceFormField::setValue gives a hint that some fundamentally different approach has to be taken.
It seems to be pretty usual case I am working with, so what is the recommended approach?
As originally mentioned in my comment, I've handled this in the past by having my template system generate different markup to facilitate testing. In my scenario, the code looked approximately like this:
// templates/user-preferences.phpt
// ...
{% if $config->isTesting() %}
{% include 'input-text.phpt' with options only %}
{% else %}
{% include 'select.phpt' with options only %}
{% endif %}
I then have a unit test that sets the production configuration and ensures there's a select.
Having thought about this overnight, I've decided this isn't the right way to do it. Behat+Mink aims to test behaviors from a browser's perspective: whatever a conventional browser can do, you can do with Behat+Mink.
But this behavior - submitting values to a form that aren't in the form element - isn't part of what a conventional browser can do. You can't conventionally tell a browser to submit "baz" when the input element accepts only "foo" or "bar".
To send this data one has to, by definition, not use a browser. Therefore, Behat+Mink isn't the right tool for this job.
I think the proper way to test this case is to use a unit test to pump the out of bounds data into the accepting form on the server side. This might be your controller, or it might be a dedicated form class.