カスタムパス/モデルへのPUTの仕様作成

モデルを追加するプラグインに取り組んでいます。そのモデル(そしてコントローラーも?)が期待通りに動作していることをテストする仕様(specs)を書く試み中です。

この 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)

私が書こうとしている、そのパスへの更新をテストする仕様(spec)は以下の通りです。混乱しているのは、コントローラーに無数の 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

昨日はほぼ一日中これに取り組みました。解決策やデバッグのテクニックに関するヒントがあれば、非常に助かります。

user_id: user.id, hostname: 'bogus.invalid', request_status: 'not updated' というパラメータで s = Pfaffmanager::Server.createServerFromParams を呼び出すモデルを作成した場合、リクエストテストが正しく機能するように、前回の例でユーザーをファブリケートしたのと同様に、これをファブリケートする必要があるかもしれません。

ああ、つまり実際の create ではなく fabricate を使っていることが問題なのかもしれませんね。他の仕様では、例えば上記のコードで Server を作成し、その後 get を実行してサーバー一覧を取得し、正しいホスト名を持つサーバーが存在することと、正しい数のサーバーが返されることを確認しています。

ただ、やはり「正しい方法」で fabricate する方法を調べておくのが良さそうですね。

ご親切にご助言いただき、ありがとうございます。次はそれを試してみます!

問題(少なくともその一つ)を解決しました。model.rb ファイルに、variable_that_is_nil['xxx'] のような処理を含むエラーがある場合、モデルは失敗しますが、ブラウザで「テスト」した際に Rails ログに表示されるようなエラーが、spec のログには表示されません。そのため、モデルやコントローラーが呼び出されていないように見えることがありますが、実際には呼び出されています。

しかし、実際に Fabricator も作成しました。@justin、後押ししてくれてありがとう!