Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rspec:如何将expect-to-receive与尚不存在的资源一起使用?_Ruby On Rails_Ruby_Rspec - Fatal编程技术网

Ruby on rails Rspec:如何将expect-to-receive与尚不存在的资源一起使用?

Ruby on rails Rspec:如何将expect-to-receive与尚不存在的资源一起使用?,ruby-on-rails,ruby,rspec,Ruby On Rails,Ruby,Rspec,在通过post请求调用的操作中,我正在创建资源调用RequestOffer,并使用创建的资源作为参数与ActionMailer一起发送电子邮件: @request_offer = RequestOffer.new(request_offer_params) if @request_offer.save RequestOfferMailer.email_team(@request_offer).deliver_later end 在我的控制器规范中,我想测试我的RequestOfferM

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

@request_offer = RequestOffer.new(request_offer_params)
if @request_offer.save
    RequestOfferMailer.email_team(@request_offer).deliver_later
end
在我的控制器规范中,我想测试我的RequestOfferMailer是否使用方法email_team调用,并将resource@request_offer作为参数

当我想使用expectXXX.to receiveYYY.withZZZ时,我找到的唯一方法是在发出POST请求之前声明我的期望。然而,ZZZ是根据这个帖子请求创建的,所以我之前没有办法设定我的期望

# 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

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

确保该参数是RequestOffer的一个实例就足够了吗?然后可以使用matcher的实例。例如:

expect(RequestOfferMailer).to receive(:email_team).with(instance_of(RequestOffer)).and_return(message_delivery)

我在Rspec 3.0文档中发现了这个选项:

确保参数是RequestOffer的实例是否足够?然后可以使用matcher的实例。例如:

expect(RequestOfferMailer).to receive(:email_team).with(instance_of(RequestOffer)).and_return(message_delivery)

我在Rspec 3.0文档中找到了这个选项:

如果这是一个功能测试,那么我会将控制器测试与数据库隔离。您可以使用instance_double和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”来声明要创建的模型的双实例。通过设置类的期望值,可以将实例double注入测试并与DB隔离。请注意,before块中的“allow”调用用于为设置mailer对象期望值的后续规范提供服务;第一个测试中的“expect”调用仍然能够对调用进行断言。

如果这是一个功能测试,那么我会将控制器测试与数据库隔离。您可以使用instance_double和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”来声明要创建的模型的双实例。通过设置类的期望值,可以将实例double注入测试并与DB隔离。请注意,before块中的“allow”调用用于为设置mailer对象期望值的后续规范提供服务;第一次测试中的“expect”调用仍然能够对该调用进行断言。

理想情况下,我会测试更多。然而,你的链接提供了一些可能是解决方案的东西,用户和客户匹配者:我可以定义一个检查它是否是RequestOffer的实例,同时检查重要属性是否相等,例如电子邮件模板中需要的电话号码和电子邮件。让我们看看是否有人有更简单的解决方案,但已经感谢您的提示!理想情况下,我会测试更多。然而,你的链接提供了一些可能是解决方案的东西,用户和客户匹配者:我可以定义一个检查它是否是RequestOffer的实例,同时检查重要属性是否相等,例如电子邮件模板中需要的电话号码和电子邮件。让我们看看是否有人有更简单的解决方案,但已经感谢您的提示!