#ruby-on-rails #email #testing #rspec
#ruby-on-rails #Адрес электронной почты #тестирование #rspec
Вопрос:
У меня есть сотрудник, который отправляет электронную почту пользователям, когда появляются новые отзывы. Я хотел разрешить пользователю не соглашаться с этим (с флагами Ши-тцу). Вопрос в следующем: как я могу проверить (с помощью Rspec) FedbackMailer.new_feedback
, выполняется ли строка?
account.users.each do |user|
return if (user.no_notifications || user.just_summary)
FeedbackMailer.new_feedback(account.id, feedback_id, user.id).deliver_later
end
Ответ №1:
Вы можете использовать rspec-mocks .
mailer = instance_double
allow(FeedbackMailer).to receive(:new_feedback).with(account_id, feedback_id, user_id).and_return(mailer)
allow(mailer).to receive(:deliver_later)
## do stuff ##
expect(mailer).to have_received(:deliver_later)
Вы также можете игнорировать .with
, если у вас нет аргументов для передачи в этот момент.
Другим решением является установка конфигурации config.action_mailer.delivery_method = :test
и проверка, изменилось ли количество доставок.
expect {
## code that deliver the email
}.to change { ActionMailer::Base.deliveries.count }.by(1)
Ответ №2:
Допустим, ваша логика инкапсулирована в следующий метод в классе MyClass
class MyClass
def my_method
account.users.each do |user|
return if (user.no_notifications || user.just_summary)
FeedbackMailer.new_feedback(account.id, feedback_id, user.id).deliver_later
end
end
end
RSpec.describe MyClass, type: :model do
context "#my_method" do
it "should send new feedback" do
user_obj = create_user
expect(user_obj.no_notifications).to be_falsey
#OR
#expect(user_obj.just_summary).to be_falsey
account_obj = create_account
account_obj.users << user_obj
expect(account_obj.users).to include(user_obj)
expect(FeedbackMailer).to receive(:new).with(account_obj.id, feedback_id, user_obj.id)
# OR in case you don't have feedback_id then you can use
# expect(FeedbackMailer).to receive(:new).with(account_obj.id, kind_of(Numeric), user_obj.id)
# You should also setup expectation here that `FeedbackMailer` gets enqueued to ensure
# that your method also gets invoked and the job also gets enqueued.
subject.my_method
end
end
end
Надеюсь, это поможет. Спасибо.