[ruby-on-rails] Rspec 3 플래시 메시지 테스트 방법

rspec을 사용하여 컨트롤러의 동작 및 플래시 메시지 존재를 테스트하고 싶습니다.

액션 :

def create
  user = Users::User.find_by_email(params[:email])
  if user
    user.send_reset_password_instructions
    flash[:success] = "Reset password instructions have been sent to #{user.email}."
  else
    flash[:alert] = "Can't find user with this email: #{params[:email]}"
  end

  redirect_to root_path
end

사양 :

describe "#create" do
  it "sends reset password instructions if user exists" do
    post :create, email: "email@example.com"
    expect(response).to redirect_to(root_path)
    expect(flash[:success]).to be_present
  end
...

하지만 오류가 있습니다.

Failure/Error: expect(flash[:success]).to be_present
   expected `nil.present?` to return true, got false



답변

의 존재를 테스트하고 flash[:success]있지만 컨트롤러에서 사용하고 있습니다.flash[:notice]


답변

플래시 메시지를 테스트하는 가장 좋은 방법은 shoulda gem에서 제공합니다 .

다음은 세 가지 예입니다.

expect(controller).to set_flash
expect(controller).to set_flash[:success]
expect(controller).to set_flash[:alert].to(/are not valid/).now


답변

플래시 메시지의 내용에 더 관심이있는 경우 다음을 사용할 수 있습니다.

expect(flash[:success]).to match(/Reset password instructions have been sent to .*/)

또는

expect(flash[:alert]).to match(/Can't find user with this email: .*/)

해당 메시지가 중요하거나 자주 변경되지 않는 한 특정 메시지를 확인하지 않는 것이 좋습니다.


답변

와: gem 'shoulda-matchers', '~> 3.1'

에서 .now직접 호출해야합니다 set_flash.

한정자와 set_flash함께 사용 하고 다른 한정자 뒤에 now지정하는 now것은 더 이상 허용되지 않습니다.

now바로 뒤에 사용하고 싶을 것 set_flash입니다. 예를 들면 :

# Valid
should set_flash.now[:foo]
should set_flash.now[:foo].to('bar')

# Invalid
should set_flash[:foo].now
should set_flash[:foo].to('bar').now


답변

또 다른 접근 방식은 컨트롤러에 플래시 메시지가 있다는 사실을 제외하고 대신 통합 테스트를 작성하는 것입니다. 이렇게하면 JavaScript를 사용하거나 다른 방법으로 메시지를 표시하기로 결정한 후 테스트를 변경할 필요가 없을 가능성이 높아집니다.

참조 https://stackoverflow.com/a/13897912/2987689


답변