在通过POST请求调用的操作中,我创建了一个名为RequestOffer
的资源,并使用创建的资源作为参数发送了一封包含ActionMailer
的电子邮件:
@request_offer = RequestOffer.new(request_offer_params)
if @request_offer.save
RequestOfferMailer.email_team(@request_offer).deliver_later
end
当我的控制器规范时,我想测试我的RequestOfferMailer
是使用带有资源@request_offer
作为参数的方法email_team
调用的。
当我想使用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
你知道怎么解决这个问题吗?
3条答案
按热度按时间vuktfyat1#
如果这是一个功能测试,那么我会将控制器测试从数据库中分离出来。您可以使用
instance_doubles
和let语句来执行此操作。下面是一个示例,您可以根据自己的目的进行扩展关键是使用‘let’声明一个与您打算创建的模型相同的示例。通过设置对类的期望,您可以将示例Double注入到测试中,并与数据库隔离。请注意,BEFORE块中的“Allow”调用是为了服务于设置对邮件程序对象的期望的稍后规范;第一个测试中的“Expect”调用仍将能够对该调用进行Assert。
hlswsv352#
确保参数是
RequestOffer
的示例就足够了吗?然后,您可以使用instance_of
匹配器。例如:我在RSpec 3.0文档中找到了此选项:https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/setting-constraints/matching-arguments
ujv3wf0j3#
with
方法的最后一个参数是一个块。你可以在那里打开争论,做任何你想做的事情。如果您甚至不确定期望的对象类型,也可以将
instance_of
匹配器设置为anything
。