测试失败:sign_in(Fabricate(:user))

我有一个规范在几天前开始失败。看起来是由于时区(timezone)相关的问题?我不觉得这是我的插件的错,但也许我漏掉了什么?

require 'rails_helper'

describe TopicDefaultTag::ActionsController do
  before do
    Jobs.run_immediately!
  end

  it 'can list' do
    sign_in(Fabricate(:user))
    get "/topic-default-tag/list.json"
    expect(response.status).to eq(200)
  end
end
正在运行 Rspec: plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb
运行规范时加载插件

加载 ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb 时发生错误。
Failure/Error: UserOption.create!(user_id: id)

NoMethodError:
  #<UserOption:0x000055dd7af16ca8> 没有 `timezone` 方法
  可能的意思是:timeout
# ./app/models/user.rb:1343:in `create_user_option'
# (eval):19:in `block (2 levels) in run_file'
# ./spec/rails_helper.rb:79:in `<top (required)>'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `require'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `<top (required)>'
未找到任何示例。


执行完毕,耗时 0.00005 秒(文件加载耗时 3.52 秒)
0 个示例,0 个失败,1 个错误发生在示例之外
1 个赞

听起来你的 user_options 表中缺少了时区列。你最近是否在测试数据库中运行过迁移?RAILS_ENV=test bin/rake db:migrate

2 个赞

哎呀,没有!我还没有。我在开发数据库上运行了迁移,但没有在测试数据库上运行。谢谢,David!

我现在不太明白发生了什么,但这问题可能没那么初级。:wink:

2 个赞

当缺少迁移时,您应该会收到一条消息。

但这仅在您使用 rails_helper 时才有效。我怀疑您需要在 spec 文件顶部添加 require "rails_helper"。这也可能解决您遇到的其他问题。

编辑:嗯……也许我们应该在 .rspec 文件中添加 --require rails_helper,这样就不需要手动添加了:thinking:

2 个赞

这听起来像是我会犯的那种愚蠢的错误!唉,我确实有 require 'rails_helper'

也许运行 ./bin/rake autospec 而不是 bundle exec rake autospec 是我的问题,但它在 Travis 上仍然失败。现在这个测试规范似乎为我那一个小小的测试做了一大堆我不理解的事情,不过我就先等等看会发生什么吧。

再次感谢。

2 个赞

我在 sign_in 辅助函数上遇到了问题,非常感谢您的帮助!:exploding_head: :

当在该测试中使用它时,它似乎无法提供 current_user,并返回 403 错误(而不是 200):

我这样运行测试以进行隔离,但两种情况下都无法正常工作:

LOAD_PLUGINS=1 RAILS_ENV=test rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb:32

如果我在相应的控制器中添加一个 byebug 并检查 current_user,发现它是 nil(所以我猜这就是导致 403 的原因):

Randomized with seed 50945

[5, 14] in /home/merefield/code/discourse-follow/app/controllers/follow/follow_controller.rb
    5:   def update
    6:     params.require(:username)
    7:     params.require(:follow)
    8:     byebug
    9:
=> 10:     raise Discourse::InvalidAccess.new unless current_user
   11:     raise Discourse::InvalidParameters.new if current_user.username == params[:username]
   12:
   13:     if user = User.find_by(username: params[:username])
   14:       updater = Follow::Updater.new(current_user, user)
(byebug) current_user
nil

你上面有创建该用户的吗?(我记不清那具体叫什么,也不记得具体怎么操作了。哦,也许是“合成器”?是你合成出了那个用户吗?

(或者我可能没看到,因为我在用手机。)

1 个赞

是的,用户对象已创建成功。问题出在 sign_in 方法中,或者与环境有关?(但这应该是受控的)

1 个赞

经过进一步调查,我发现以下情况:

def current_user 中(discourse/lib/auth/default_current_user_provider.rb at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub

@env.key?(CURRENT_USER_KEY)true

因此 current_user 的值为 @env[CURRENT_USER_KEY]

然而,当这行代码在我的控制器中于测试运行时被调用时,其值为 nil

  def update
    params.require(:username)
    params.require(:follow)

    raise Discourse::InvalidAccess.new unless current_user

我不确定为什么在规范中登录用户后,@env[CURRENT_USER_KEY] 会是 nil

我注意到在测试运行期间,current_user 在单个测试中被多次调用,有时该属性有值,但并非每次调用都有值,尤其是在关键时刻却没有值。

您是否安装了其他可能干扰 current_user 对象的插件?我克隆了 discourse-follow,该测试用例在我这里可以正常运行:

❯ LOAD_PLUGINS=1 bin/rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb   

Randomized with seed 28704
...

Finished in 0.45075 seconds (files took 3.34 seconds to load)
3 examples, 0 failures

Randomized with seed 28704
2 个赞

啊,谢谢验证,David!那看来是我开发环境中的某个特殊问题!

不,没有安装其他插件(除了捆绑插件和数据探索器),但既然在你那边能运行,我打算搭建一个全新的干净 Docker 开发实例,看看能否在那里成功运行。干杯!:beers:

1 个赞

是的,已在 Docker 开发环境中运行:

d/rake plugin:spec["discourse-follow"]

谢谢!!

3 个赞

此主题已在 20 小时后自动关闭,不再允许新回复。