我如何在rails rspec中测试cookie到期

时间:2011-06-27 12:11:44

标签: ruby-on-rails-3 cookies rspec

在rspec中设置cookie存在很多困惑 http://relishapp.com/rspec/rspec-rails/v/2-6/dir/controller-specs/file/cookies

在您的控制器中,通常可以写

cookies['transaction_code'] = { :expires => 300.seconds.from_now, :value => c }

但在rspec中我只能写

request.cookies['transaction_code'] = transaction_code

如果我说

request.cookies['transaction_code'] = { :expires => 300.seconds.from_now, :value => c }

我在我的控制器中将哈希值作为cookie ['transaction_code']的值。

现在我的问题是:如何在rspec控制器测试示例中设置/测试cookie到期时间?

更新:在几秒钟内思考:我的意思是:我如何测试控制器是否按预期对过期的cookie作出反应,但事实上,如果我信任cookie实现,过期的cookie就像没有cookie一样,我应该做,毕竟也许我的问题毫无意义。如果是这种情况,我需要测试(另一个)控制器操作是否正确设置了一个到期的cookie,但是如果测试中的cookies ['transaction_code']只返回值,我该怎么做呢?

4 个答案:

答案 0 :(得分:17)

浏览器do not send cookie attributes back to the server。这就是您只能将键值对发送到操作的原因。

因为您可以假设Rails,Rack和浏览器使用参数做正确的事情,所以您真正需要测试的是您的代码传递给CookieJar的参数。

要在控制器设置cookie 中测试正确设置过期,您可以删除#cookies方法并确保将正确的设置传递给它。

# app/controllers/widget_controller.rb
...
def index
    cookies[:expiring_cookie] = { :value   => 'All that we see or seem...', 
                                  :expires => 1.hour.from_now }
end
...

# spec/controllers/widget_controller_spec.rb
...
it "sets the cookie" do
  get :index
  response.cookies['expiring_cookie'].should eq('All that we see or seem...')
                                               # is but a dream within a dream.
                                               #                - Edgar Allan Poe
end

it "sets the cookie expiration" do
  stub_cookie_jar = HashWithIndifferentAccess.new
  controller.stub(:cookies) { stub_cookie_jar }

  get :index
  expiring_cookie = stub_cookie_jar['expiring_cookie']
  expiring_cookie[:expires].to_i.should be_within(1).of(1.hour.from_now.to_i)
end
...

测试远远超过这个沸腾海洋。在某些时候,您必须假设您所在的堆栈(例如,Rails,Rack,Web服务器,TCP / IP,操作系统,Web浏览器等)正常工作并专注于您控制的代码。

答案 1 :(得分:1)

使用Timecop的另一个选项:

Timecop.freeze(Time.now)

expect(controller.send(:cookies)).to receive(:[]=).with('cookie_name',
  value:   'whatever',
  expires: 1.hour.from_now
)

get :index

答案 2 :(得分:0)

在您的规范中将request.cookies ['transaction_code']设置为CGI :: Cookie。 http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI/Cookie.html#M000169

答案 3 :(得分:0)

我是从未来来的:

  it 'sets the cookie expiration' do
    stub_cookie_jar = HashWithIndifferentAccess.new
    allow(controller).to receive(:cookies).and_return(stub_cookie_jar)
    get :index
    expiracy_date = stub_cookie_jar[:expires]
    expect(expiracy_date).to be_between(1.hour.from_now - 1.minutes, 
                                        1.hour.from_now)
  end