In RSpec, what is the difference between message waiting (receiving) and test spy (has_received)?

In RSpec (specifically rspec-mocks ), what is the difference between Message Expectations and Test Spies ? They seem similar and appear next to each other as separate sections in the readme.

i.e. what's the difference between:

expect(validator).to receive(:validate) # message expectation 

and

 expect(validator).to have_received(:validate) # test spy 
+8
ruby-on-rails testing mocking rspec
source share
2 answers

Message expectations can be set on any object and represent an announcement that something will happen (or will not happen) with this object in the future. If the expected violation is violated during a subsequent test, the test will fail at the time of the violation. If the wait was not completed by the end of the test, the test will also fail.

The have_received family of methods works only on test counterparts and checks what happened to the double in the past, since the double creation up through the current method call. It succeeds or fails at that moment. The term "trial spy" is a little misleading, because support for this reverse mechanism is a standard part of rspec-mocks at this point. You are not doing anything "special" to create a "test spy."

+6
source share

You cannot always use spyware when testing, mainly for classroom expectations.

Example:

 expect(User).to receive(:new) 

There is no way to do this with a spy (unless you are injecting dependencies).

Now you can do the following:

 user = double('user', save: true) expect(User).to receive(:new).and_return user User.new.save expect(user).to have_received(:save) 

You clearly see that:

  • you must set expectations on a real object before running real code (this looks weird to set expectations before running code)

  • you can set the expectation of spies after real code, which is more natural

+3
source share

All Articles