Это не отображается в вашем коде, но я чувствую, что вы звоните по номеру code
до того, как настроите свои ожидания получения. Проще говоря, выполнение кода должно выглядеть следующим образом:
it 'something' do
expect(subject.b).to receive(:to_s)
# write code here that would eventually call `a.b.to_s` (as you have said)
# i.e.
# `subject.some_method` (assuming `some_method` is your method that calls `a.b.to_s`
# don't call `subject.some_method` before the `expect` block above.
end
- Кроме того, на случай, если вы еще не знаете, убедитесь, что это тот же экземпляр объекта, который вы передаете, чтобы ожидать:
expect(THE_ARG) ... receive()
и объект, который вы тестируете, для вызова. Вы можете проверить, что они одинаковы, если они имеют одинаковые object_id
:
it 'something' do
puts subject.b.object_id
# => 123456789
subject.some_method
end
# the class/method you're unit-testing:
class Foo
def some_method
# ...
puts b.object_id
# => 123456789
# ^ should also be the same
В противном случае, если это не тот же объект (object_id не совпадает), вам придется использовать либо expect_any_instance_of
(который я использую только в крайнем случае, поскольку он потенциально опасен, поскольку он ожидает "любой экземпляр") ... или вы можете заглушить цепочку a.b.to_s
объектов в вашем файле спецификации.
Еслитрудно заглушить всю цепочку, но в то же время, избегайте ловушек использования expect_any_instance_of
, я использую другой вариант, который я использую, чтобы сбалансировать удобство и точность спецификации:
it 'something' do
expect_any_instance_of(subject.b.class).to receive(:to_s).once do |b|
expect(b.id).to eq(subject.b.id)
# the above just compares the `id` of the records (even if they are different objects in different memory-space)
# to demonstrate, say I do puts here:
puts b
# => #<SomeRecord:0x00005600e7a6f3b8 id:1 ...>
puts subject.b
# => #<SomeRecord:0x00005600e4f04138 id:1 ...>
puts b.id
# => 1
puts subject.b.id
# => 1
# notice that they are different objects (0x00005600e7a6f3b8 vs 0x00005600e4f04138)
# but the attribute id is the same (1 == 1)
end
subject.some_method
end