我正在测试一个类的初始化块,如下所示
class A
attr_accessor :client
def initialize(options, configuration)
self.client = B.new(options)
config = C.new(
url: configuration[:url],
headers: configuration[:headers],
username: configuration[:username],
password: configuration[:password]
)
client.configure(config)
end
end
class C
def initialize(options)
# does something with options hash
end
end
class B
def initialize(options)
# does something with options hash
end
def configure(config)
# some configuration with config object
end
end
我的测试用例如下:
let(:options) {
{
force_basic_auth: true
}
}
let(:configuration) {
{
url: 'https://localhost:3000',
headers: { awesome: true },
username: 'test',
password: 'pass'
}
}
let(:api_config) {
C.new(configuration)
}
it 'configures object with passed params' do
expect_any_instance_of(B).to receive(:configure)
.with(api_config)
A.new(
options,
configuration
)
end
这使我的测试用例失败,因为在初始化块中创建的对象与我在期望中使用的api_config的object_id
具有不同的object_id
。
-[#<C:0x00000002b51128 @url="https://localhost:3000", @headers={:awesome=>true}, @username="test", @password="pass">]
+[#<C:0x00000002a1b628 @url="https://localhost:3000", @headers={:awesome=>true}, @username="test", @password="pass">]
看到失败我在想是否是在初始化块中直接传递这些对象的最佳做法。我的意思是我可以通过直接传递初始化块中的对象来修复它。
有许多函数正在初始化A
类,并且传递了一个哈希选项,因为我正在以当前的方式执行它。
有没有办法期望在rspec中传递的对象的内容而不是验证对象是否相同?在初始化中直接传递对象是一种更好的方法吗?
答案 0 :(得分:1)
您可以定义任意期望处理以检查所选参数的值(请参阅here):
it 'configures object with passed params' do
expect_any_instance_of(B).to receive(:configure) do |config|
expect(config).to be_a(C)
expect(config.url).to eq(configuration[:url])
expect(config.headers).to eq(configuration[:headers])
# ...
end
A.new(
options,
configuration
)
end
答案 1 :(得分:0)
您需要B.configure(config)
下的配置哈希(而不是对象),因此您的类必须稍微更改以适应。
班级档案
class A
attr_accessor :client
def initialize(options, configuration)
self.client = B.new(options)
config = C.new(
url: configuration[:url],
headers: configuration[:headers],
username: configuration[:username],
password: configuration[:password]
)
client.configure(config.options)
end
end
class C
attr_reader :options
def initialize(options)
@options = options
end
end
class B
def initialize(options)
# does something with options hash
end
def configure(config)
# some configuration with config object
end
end
以下是您的RSpec代码的样子。
describe do
let(:options) do
{
force_basic_auth: true
}
end
let(:configuration) do
{
url: 'https://localhost:3000',
headers: { awesome: true },
username: 'test',
password: 'pass'
}
end
let(:my_a_object) { A.new(options, configuration) }
let(:my_b_object) { B.new(options) }
it 'configures object with passed params' do
allow(B).to receive(:new).with(options).and_return(my_b_object)
expect(my_b_object).to receive(:configure).with(configuration)
my_a_object
end
end