首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RSpec:请求规范中的存根控制器方法

RSpec:请求规范中的存根控制器方法
EN

Stack Overflow用户
提问于 2020-03-19 14:39:20
回答 2查看 1.1K关注 0票数 1

我正在编写一个RSpec request spec,它大致看起来像(为了简短起见,略作缩写):

代码语言:javascript
复制
describe 'Items', type: :request do
  describe 'GET /items' do
    before do
      allow_any_instance_of(ItemsController).to receive(:current_user).and_return(user)
      get '/items'
      @parsed_body = JSON.parse(response.body)
    end

    it 'includes all of the items' do
      expect(@parsed_body).to include(item_1)
      expect(@parsed_body).to include(item_2)
    end
  end
end

控制器看起来像这样:

代码语言:javascript
复制
class ItemsController < ApplicationController
  before_action :doorkeeper_authorize!
  def index
    render(json: current_user.items)
  end
end

正如您所看到的,我正在尝试存根doorkeeper的current_user方法。

测试目前已通过,控制器按预期工作。我的问题是关于这条线:

代码语言:javascript
复制
allow_any_instance_of(ItemsController).to receive(:current_user).and_return(user)

我根据How to stub ApplicationController method in request spec中的答案写了这一行,它很有效。然而,the RSpec docs call it a "code smell"rubocop-rspec抱怨说,"RSpec/AnyInstance: Avoid stubbing using allow_any_instance_of“。

一种替代方法是获取对控制器的引用并使用instance_double(),但我不确定如何从请求规范中获取对控制器的引用。

我应该如何编写此测试避免代码气味/遗留测试方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-20 01:30:01

你应该是去度假的。

我认为正确的方法是在请求规范中尽可能避免存根,doorkeeper需要一个令牌来授权,所以我会这样做:

代码语言:javascript
复制
describe 'Items', type: :request do
  describe 'GET /items' do
    let(:application) { FactoryBot.create :oauth_application }
    let(:user)        { FactoryBot.create :user }
    let(:token)       { FactoryBot.create :access_token, application: application, resource_owner_id: user.id }
    before do
      get '/items', access_token: token.token
      @parsed_body = JSON.parse(response.body)
    end

    it 'includes all of the items' do
      expect(@parsed_body).to include(item_1)
      expect(@parsed_body).to include(item_2)
    end
  end
end

下面是这些工厂可能是什么样子的some examples

最后,非常好的点数!

票数 1
EN

Stack Overflow用户

发布于 2020-03-19 15:11:22

你有没有想过根本不嘲笑current_user

如果您在请求规范之前编写了一个测试助手来登录user,那么current_user将被自动填充,就好像它是一个真实用户一样。代码将如下所示:

代码语言:javascript
复制
before do
  sign_in user
  get '/items'
  @parsed_body = JSON.parse(response.body)
end

如果您使用devise gem进行身份验证,它有一个关于该here的很好的编写维基页面。

@dhh也推荐使用这种方法here

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60752058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档