I test my application with Cucumber and it worked before I've added auto-detection of locales from WWW browser in application_controller.rb:
before_filter :set_locale
private
def set_locale
xxx = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
if xxx.match /^(en|fr)$/
I18n.locale = xxx
else
I18n.locale = 'en'
end
end
I have a scenario:
Scenario: Successful sign up
Given I am an anonymous user
And I am on the home page
When ...
When I run cucumber, I get an error:
Given I am an anonymous user # features/step_definitions/user_steps.rb:7
And I am on the home page # features/step_definitions/webrat_steps.rb:6
private method `scan' called for nil:NilClass (NoMethodError)
C:/workspace/jeengle/app/controllers/application_controller.rb:33:in `set_locale'
c:/worktools/ruby/lib/ruby/1.8/benchmark.rb:308:in `realtime'
(eval):2:in `/^I am on (.+)$/'
features/manage_users.feature:8:in `And I am on the home page'
I have tried to do it in before statement in step_definitions folder:
Before do
request.env['HTTP_ACCEPT_LANGUAGE'] = "en"
end
but I've got another error:
开发者_开发百科undefined method `env' for nil:NilClass (NoMethodError)
Does anybody know how to initialize/emulate request.env['HTTP_ACCEPT_LANGUAGE'] in Cucumber?
UPDATED
Cucumber test passed when I rewritted set_locale method:
xxx = request.env['HTTP_ACCEPT_LANGUAGE']
if xxx
xxx = xxx.scan(/^[a-z]{2}/).first
if xxx.match /^(en|ru)$/
I18n.locale = xxx
end
else
I18n.locale = 'en'
end
It's not a solution but it works.
Actually the problem lies in Webrat, not Cucumber. The sequence of events is (roughly)
- Cucumber runs your feature
- When the "I am on the home page" step is reached, it invokes Webrat to make the request to the controller
- Webrat constructs a request and sends it to the controller
- Step fails because the request does not have an "Accept-Language" header
Apparently Webrat does not add this header when it builds the request. However, Webrat gives you a workaround: the "header" method, with which any header can be set for the duration of the request.
So to make this work add a step that puts in the header, e.g.:
Given /^an Accept Language header$/ do
header "Accept-Language", "en;en-us" # or whatever value you need for testing
end`
Run this step before you visit a page and Webrat is no longer confused.
btw I got this from The Rspec Book, which really does a good job explaining how this BDD stuff fits together.
Another way is "same-same, but different". You can add before statement in your step definition file:
Before do
header 'Accept-Language', 'en-US'
end
This will be executed before each scenario and they remain clear and clean.
精彩评论