Joh*_*ith 4 ruby rspec ruby-on-rails
在通过发布请求调用的操作中,我创建资源调用并使用创建的资源作为参数RequestOffer发送电子邮件:ActionMailer
@request_offer = RequestOffer.new(request_offer_params)
if @request_offer.save
RequestOfferMailer.email_team(@request_offer).deliver_later
end
Run Code Online (Sandbox Code Playgroud)
当我的控制器规范时,我想测试是否使用以资源作为参数的RequestOfferMailer方法调用我的控制器。email_team@request_offer
当我想要 user 时expect(XXX).to receive(YYY).with(ZZZ),我发现的唯一方法是在发出 POST 请求之前声明我的期望。然而,ZZZ是由这个POST请求创建的,所以我之前没有办法设定我的期望。
# Set expectation first
message_delivery = instance_double(ActionMailer::MessageDelivery)
# ZZZ used in .with() does not exist yet, so it won't work
expect(RequestOfferMailer).to receive(:email_team).with(ZZZ).and_return(message_delivery)
expect(message_delivery).to receive(:deliver_later)
# Make POST request that will create ZZZ
post :create, params
Run Code Online (Sandbox Code Playgroud)
知道如何解决这个问题吗?
如果这是一个功能测试,那么我会将控制器测试与数据库隔离。您可以通过使用instance_doubles和 let 语句来做到这一点。这是一个您可能希望根据您的目的进行扩展的示例
describe '/request_offers [POST]' do
let(:request_offer) { instance_double(RequestOffer, save: true) }
before do
allow(RequestOffer).to receive(:new).
with(...params...).
and_return(request_offer)
end
it 'should instantiate a RequestOffer with the params' do
expect(RequestOffer).to receive(:new).
with(...params...).
and_return(request_offer)
post '/request_offers', {...}
end
it 'should email the request offer via RequestOfferMailer' do
mailer = instance_double(ActionMailer::MessageDelivery)
expect(RequestOfferMailer).to receive(:email_team).
with(request_offer).and_return(mailer)
post '/request_offers', {...}
end
end
Run Code Online (Sandbox Code Playgroud)
关键是使用“let”来声明您想要创建的模型的实例双精度。通过对类设置期望,您可以将实例双重注入测试中并与数据库隔离。请注意,before 块中的“allow”调用是为了服务于对邮件程序对象设置期望的后续规范;第一个测试中的“expect”调用仍然能够对调用做出断言。
| 归档时间: |
|
| 查看次数: |
24709 次 |
| 最近记录: |