0

我实际上是在使用 RSpec 编写测试。以下代码在spec/requests/tasks_spec.rb.


require 'spec_helper'

describe "Tasks" do

  env_headers = {'HTTP_ACCEPT' => Mime::JSON, "devise.mapping" => Devise.mappings[:user] }

  describe "GET /tasks" do
    context "with valid credentials" do
      user = FactoryGirl.build(:user)
      authorization_header =  ActionController::HttpAuthentication::Basic.encode_credentials(user.authentication_token, nil)
      env_headers['HTTP_AUTHORIZATION'] = authorization_header

      it "should succeed" do
        get '/tasks', nil, env_headers
        response.status.should eq(200)
      end
    end

    context "with invalid credentials" do
      authorization_header = ActionController::HttpAuthentication::Basic.encode_credentials("123456", nil)
      env_headers['HTTP_AUTHORIZATION'] = authorization_header

      it "should fail" do
        get '/tasks', nil, env_headers
        response.status.should eq(401)
      end
    end

  end
end

因为我不仅要测试 GET(还有 PUT、DELETE 等),我想避免与用户实例化有关的代码重复。如果我真的移动到上下文之外,我将因为范围问题user = FactoryGirl.build(:user)而无法访问变量。user

  • 我想知道 RSpec 中是否有一个最佳实践来让这个用户在每个上下文中都可以重用。

  • 还有更多,但如果我可以使其仅可用于特定上下文,例如(在我的情况下):(因为我的 上下文context "with valid credentials" 不需要用户),则可选。with invalid credentials

更新 :

通过使用 let 我仍然遇到范围问题,这是由于一个愚蠢的错误。我在询问我的 it 块之外的用户。下面的代码没问题:


describe "Tasks" do

  let(:user) { FactoryGirl.build(:user) }

  describe "GET /tasks" do
    context "with valid credentials" do

      it "should succeed" do
        authorization_header =  ActionController::HttpAuthentication::Basic.encode_credentials(user.authentication_token, nil)
        env_headers['HTTP_AUTHORIZATION'] = authorization_header

        get '/tasks', nil, env_headers
        response.status.should eq(200)
      end
    end

4

1 回答 1

0

您可以将以下内容放在您的上下文之外:

describe "Tasks" do

  let(:user) { FactoryGirl.build(:user) }

  # your tests

let是延迟加载的,这意味着每次只有在你的规范中调用它时才会评估它user.a_method,或者只是调用user.

let仅供参考,您可以通过添加“!”来指定 RSpec 直接评估

let!(:foo) { 'foo' } # will be evaluated right away
于 2013-07-19T08:20:52.063 回答