[英]How do you skip a service call in a rspec test
Im writing a test for this service. 我正在为此服务编写测试。
def run
sort_offers(product).each do |product_code|
......
offer.update(poduct_params)
Importer::Partner.get_details(product_code).new
end
end
It's calling a service which in some cases will override the values that were saved when running offer.update(product_prams)
. 它正在调用服务,在某些情况下,该服务将覆盖运行offer.update(product_prams)
时保存的值。 How would I go about skipping the service call within my test? 如何在测试中跳过服务呼叫?
Here is the example of my test 这是我测试的例子
context 'is valid' do
.... .....
before do
Importer::ProductCodes(product).run
end
it ......
end
RSpec has a very capable stubbing and mocking library built in ( rspec mocks ). RSpec内置了一个功能非常强大的存根和模拟库( rspec嘲笑 )。
require 'spec_helper'
module Importer
class Partner
def self.get_details(product_code)
"original return value"
end
end
end
class FooService
def self.run
Importer::Partner.get_details('bar')
end
end
RSpec.describe FooService do
let(:partner_double) { class_double("Importer::Partner") }
before do
stub_const("Importer::Partner", partner_double)
allow(partner_double).to receive(:get_details).and_return 'our mocked value'
end
it "creates a double for the dependency" do
expect(FooService.run).to eq 'our mocked value'
end
end
class_double
creates a double for the class and you can set the return values by using .expect
and .allow
and the mocking interface. class_double
为该类创建一个double,您可以使用.expect
和.allow
以及.expect
接口来设置返回值。 This is quite useful since you can stub out the new
or intialize
methods to return a double or spy. 这非常有用,因为您可以将new
方法或intialize
方法存根以返回double或spy。
stub_constant
will reset the constant to its previous value when the spec is done. 规范完成后, stub_constant
会将常数重置为其先前的值。
That said you can avoid the use of stub_constant
by using constructor injection in your services: 也就是说,可以通过在服务中使用构造函数注入来避免使用stub_constant
:
class PhotoImportService
attr_accessor :client, :username
def initialize(username, api_client: nil)
@username = username
@client = api_client || APIClient.new(ENV.fetch('API_KEY'))
end
def run
client.get_photos(username)
end
end
I would stub Importer::Partner.get_details
to return a double
that responds to new
: 我将对Importer::Partner.get_details
进行存根以返回一个对new
作出响应的double
:
context 'is valid' do
before do
allow(Importer::Partner).to receive(:get_details).and_return(double(new: nil))
end
# it ...
end
Depending on your needs you might want to add an expectation that the mock was called with the correct parameters and that new
was actually called on the mock too: 根据您的需求,您可能希望增加使用正确参数调用该模拟并且实际上也对该模拟调用了new
的期望:
context 'is valid' do
let(:mock) { double(new: nil) }
before do
allow(Importer::Partner).to receive(:get_details).and_return(double(new: nil))
end
it "calls the service" do
an_instance.run
expect(Importer::Partner).to have_received(:get_details).with(
foo: 'bar' # the arguments you would expect
)
expect(mock).to have_received(:new)
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.