gpt4 book ai didi

ruby-on-rails - Rspec:如何使用 expect 接收尚不存在的资源?

转载 作者:行者123 更新时间:2023-12-02 17:28:28 29 4
gpt4 key购买 nike

在通过 post 请求调用的操作中,我正在创建资源调用 RequestOffer 并使用创建的资源作为参数发送带有 ActionMailer 的电子邮件:

@request_offer = RequestOffer.new(request_offer_params)
if @request_offer.save
RequestOfferMailer.email_team(@request_offer).deliver_later
end

当我的 Controller 规范时,我想测试我的 RequestOfferMailer 是使用方法 email_team 以资源 @request_offer 作为参数调用的.

当我想要用户 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

知道如何解决这个问题吗?

最佳答案

如果这是一个功能测试,那么我会将 Controller 测试与数据库隔离开来。您可以使用 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

关键是使用“let”来声明您打算创建的模型的双实例。通过对类设置期望,您可以将实例双重注入(inject)测试并与数据库隔离。请注意,前面 block 中的“允许”调用是为了服务于稍后对邮件对象设置期望的规范;第一个测试中的“expect”调用仍然能够对调用做出断言。

关于ruby-on-rails - Rspec:如何使用 expect 接收尚不存在的资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36625449/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com