Sorry my example was slightly off (pains of trying to anonymize!), because
it's actually calling a (now) private method of a different class. Oops!
Here's a better sample:
class Post
private
def process # used to be public
# ...
end
end
class Operation
def self.call
post.process
# do other things here
end
end
RSpec.describe Operation do
subject { described_class }
it do
expect(post).to receive(:process)
subject.call
end
end
Now the test still succeeds but the code doesn't. I understand your
suggestion of testing to make sure that methods are the expected
accessibility, but this is probably too cumbersome in practice in a large
codebase.
On Tuesday, July 21, 2020 at 4:28:17 PM UTC-4 Jon Rowe wrote:
> Yep that should continue to work, from the perspective of `call` it
> doesn’t matter wether `do_something` is private or not, it is just an
> implementation detail to it.
>
> Really to catch this you should also write a spec for `do_something` in
> its own right, if its part of your “public api” it is often a good idea to
> test this.
>
> I wouldn’t advocate this, but if its too expensive to call un-mocked this
> would check its available publicly:
>
> RSpec.describe “#do_something” do
> # its too expensive to call in tests, but we want to ensure its public
> it “is a public method” do
> object = MyObject.new
> expect(object).to receive(:do_something)
> object.do_something
> end
> end
>
> However, if you’re using standard Ruby semantics, this might make more
> sense:
>
> RSpec.describe “#do_something” do
> it “is a public method” do
> object = MyObject.new
> expect(object).to respond_to(:do_something)
> end
> end
>
> Cheers
>
> Jon Rowe
> ---------------------------
> [email protected]
> jonrowe.co.uk
>
> On 21 July 2020 at 21:16, 'Daniel Vandersluis' via rspec wrote:
>
> Jon Rowe,
>
> My test looked something like this:
>
> class MyObject
> def call
> do_something
> end
>
> private
>
> def do_something # this used to be public!
> #...
> end
> end
>
> subject { MyObject.new }
>
> expect(obj).to receive(:do_something)
> subject.call # this calls do_something
>
> Regardless of whether do_something is public or private, the expectation
> passes, but when called outside of a test, the method fails with
> NoMethodError because the method became private. I totally agree that the
> tests we had were not adequate, but also it wasn't something we were able
> to catch.
>
> Daniel
>
>
--
You received this message because you are subscribed to the Google Groups
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/rspec/33f25d23-6c1e-4e01-a650-3a916fb0c2a4n%40googlegroups.com.