사용자 지정 경로/모델에 대한 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')가 생성한 모델이라면, 요청 테스트가 정상적으로 작동하려면 이전 예시에서 사용자(user)를 페브리케이션(fabricate)했던 것과 유사하게 이 모델도 페브리케이션해야 할 수 있습니다.

아. 그러니까 실제로 생성하는 대신 fabricate를 사용한 것이 문제일 수도 있겠네요. 다른 스펙에서는 위 코드를 사용해 Server를 생성한 뒤, get을 호출하여 서버 목록을 가져오고, 올바른 호스트네임을 가진 서버가 존재하는지 그리고 올바른 수의 서버가 반환되는지 확인하고 있습니다.

그래도 fabricate를 “올바르게” 사용하는 방법을 알아내는 것이 더 합리적일 것 같습니다.

도움 주셔서 정말 감사합니다. 다음에 시도해 보겠습니다!

제 문제(혹은 그중 하나)를 찾았습니다. model.rb 파일에 variable_that_is_nil['xxx']처럼 nil 변수에 접근하려는 코드 같은 오류가 있으면, 모델은 실패하지만 브라우저로 "테스트"할 때처럼 레일스 로그에 보이는 것과 달리 스펙 로그에는 아무런 오류 메시지가 표시되지 않습니다. 그래서 실제로는 모델이나 컨트롤러가 호출되고 있는데, 그렇지 않은 것처럼 보일 수 있습니다.

하지만 실제로 Fabricator를 작성했으니, @justin 님의 조언에 감사드립니다!