为自定义路径/模型编写 put 规范

我正在开发一个添加模型的插件。我试图编写测试规范,以验证模型(以及控制器?)的行为是否符合预期。

这段 Ansible 库中的代码成功地向该路径执行了 PUT 请求,并更新了模型/记录中的字段:

    headers = {
        'Api-Key': discourse_api_key,
        'Api-Username': discourse_api_username,
    }

    payload = {
        "server[request_status]": status
    }
    url = "%spfaffmanager/servers/%s" % (discourse_url, server_id)

    # raise Exception(url) 
    result = requests.put(url, data=payload, headers=headers)

这是我正在编写的用于测试该路径更新的规范。我感到困惑,因为我在控制器中有无数个 puts,但没有任何一个打印出来,尽管在模型中(例如在 before_save 调用的函数中)的 puts 却显示在我看到的 rake autospec 输出中。

我最大的猜测是我搞错了:

# frozen_string_literal: true
require 'rails_helper'

describe Pfaffmanager::ServersController do
  fab!(:user) { Fabricate(:user) }
  fab!(:admin) { Fabricate(:admin) }
  fab!(:another_user) { Fabricate(:user) }
  fab!(:trust_level_2) { Fabricate(:user, trust_level: TrustLevel[2]) }
  before do
    Jobs.run_immediately!
  end

  it 'can update status' do
    request_status = 'new status'
    sign_in(admin)
    s=Pfaffmanager::Server.createServerFromParams(user_id: user.id,
        hostname: 'bogus.invalid' , request_status: 'not updated')
    puts "can update status created server id: #{s.id}"
    params = {server: {request_status: request_status}}
    
    expect {
        put "/pfaffmanager/servers/#{s.id}", params: params
    }.to change { s.request_status }
    expect(response.status).to eq(200)
    expect(s.request_status).to eq('new status')
  end
end

昨天我几乎花了一整天时间,非常希望能得到任何关于解决方案或调试技巧的提示。

如果 s=Pfaffmanager::Server.createServerFromParams(user_id: user.id, hostname: 'bogus.invalid' , request_status: 'not updated') 是你创建的模型,那么为了让请求测试正常运行,你可能需要像之前示例中伪造用户那样,为它创建伪造数据。

哦,所以问题可能在于我使用了 fabricate 而不是实际创建?在其他测试中,例如,我会用上述代码创建一个 Server,然后执行 get 来获取服务器列表,确认存在具有正确主机名的服务器,并验证返回的服务器数量是否正确。

不过,弄清楚如何以“正确”的方式 fabricate 一个对象可能更有意义。

非常感谢你的帮助!我接下来就试试这个方法!

我找到了我的问题(至少是其中之一)。如果你的 model.rb 文件中有错误,比如尝试执行类似 variable_that_is_nil['xxx'] 的操作,模型会失败,但 spec 日志中不会像你在浏览器中“测试”时在 Rails 日志中看到的那样显示任何错误。因此,这可能会让你误以为模型或控制器没有被调用,而实际上它们已经被调用了。

不过,我确实编写了一个真正的 Fabricator,所以感谢你的推动,@justin