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를 사용하거나 다른 방법으로 메시지를 표시하기로 결정한 후 테스트를 변경할 필요가 없을 가능성이 높아집니다.