{"action":"created","issue":{"url":"https://api.github.com/repos/rspec/rspec-mocks/issues/1075","repository_url":"https://api.github.com/repos/rspec/rspec-mocks","labels_url":"https://api.github.com/repos/rspec/rspec-mocks/issues/1075/labels{/name}","comments_url":"https://api.github.com/repos/rspec/rspec-mocks/issues/1075/comments","events_url":"https://api.github.com/repos/rspec/rspec-mocks/issues/1075/events","html_url":"https://github.com/rspec/rspec-mocks/issues/1075","id":148751895,"number":1075,"title":"Extending message expectations?","user":{"login":"delner","id":3237131,"avatar_url":"https://avatars.githubusercontent.com/u/3237131?v=3","gravatar_id":"","url":"https://api.github.com/users/delner","html_url":"https://github.com/delner","followers_url":"https://api.github.com/users/delner/followers","following_url":"https://api.github.com/users/delner/following{/other_user}","gists_url":"https://api.github.com/users/delner/gists{/gist_id}","starred_url":"https://api.github.com/users/delner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/delner/subscriptions","organizations_url":"https://api.github.com/users/delner/orgs","repos_url":"https://api.github.com/users/delner/repos","events_url":"https://api.github.com/users/delner/events{/privacy}","received_events_url":"https://api.github.com/users/delner/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-04-15T19:47:20Z","updated_at":"2016-04-16T06:55:03Z","closed_at":null,"body":"Just a question for some knowledgeable RSpec folks. I'm working on implementing a callback pattern into some code of mine. I'd like to stub/mock calls to functions that implement this pattern, and make them emulate callbacks in my RSpec tests.\r\n\r\nRight now, the most stripped down version of my test looks something like:\r\n\r\n    class MyClass\r\n      def self.foo do |&block|\r\n        # If success\r\n        block.call(:success)\r\n        # If failure\r\n        block.call(:failure)\r\n      end\r\n    end\r\n\r\n    # RSpec example\r\n    expect(MyClass).to receive(:foo) { |&block| block.call(:success) }\r\n\r\nAlthough it works through some ugly use of the `and_return` block shorthand, it hurts test readability. I'd like instead to extend the RSpec mocks, in a gem, with my own MessageExpectation method `and_callback` to do the same functional thing, which might look something like:\r\n\r\n    expect(MyClass).to receive(:foo).and_callback(:success)\r\n\r\nI've been digging through the RSpec documentation and source code, and am not seeing a clear means of adding my own expectation behavior to the RSpec suite. [Another person was trying to do something similar](http://stackoverflow.com/questions/14217148/how-to-extend-rspec-mock-expectation), and Andrew Haines suggested `alias_method` to accomplish that goal.\r\n\r\nOutright monkey patching RSpec seems like a bad idea to me, but is there a cleaner alternative or support to do an extension on the suite like this? I'm all ears!"},"comment":{"url":"https://api.github.com/repos/rspec/rspec-mocks/issues/comments/210750289","html_url":"https://github.com/rspec/rspec-mocks/issues/1075#issuecomment-210750289","issue_url":"https://api.github.com/repos/rspec/rspec-mocks/issues/1075","id":210750289,"user":{"login":"myronmarston","id":49391,"avatar_url":"https://avatars.githubusercontent.com/u/49391?v=3","gravatar_id":"","url":"https://api.github.com/users/myronmarston","html_url":"https://github.com/myronmarston","followers_url":"https://api.github.com/users/myronmarston/followers","following_url":"https://api.github.com/users/myronmarston/following{/other_user}","gists_url":"https://api.github.com/users/myronmarston/gists{/gist_id}","starred_url":"https://api.github.com/users/myronmarston/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/myronmarston/subscriptions","organizations_url":"https://api.github.com/users/myronmarston/orgs","repos_url":"https://api.github.com/users/myronmarston/repos","events_url":"https://api.github.com/users/myronmarston/events{/privacy}","received_events_url":"https://api.github.com/users/myronmarston/received_events","type":"User","site_admin":false},"created_at":"2016-04-16T06:55:03Z","updated_at":"2016-04-16T06:55:03Z","body":"You can use `and_yield` to yield to a callback:\r\n\r\n``` ruby\r\nexpect(MyClass).to receive(:foo).and_yield(:success)\r\n```"}}