-
-
Notifications
You must be signed in to change notification settings - Fork 358
Bring back stub_chain (receive_message_chain) #464
Comments
You can use your original line of code and test with expect(current_something).to receive(:cool_association).and_return(cool_association)
expect(cool_association).to receive(:find_by).with(some: 123, other: 'sasd') { scoped_cool_association } Yes it's an extra line of test, but you can assert on more things, and in my opinion it helps exposes this as a code smell. If I remember correctly we took a deliberate decision not to replicate Note you could also refactor your code on your class: class CurrentSomething
def cool_assosciation_with(query = {})
self.cool_association.with(query)
end
end and then in your tests expect(current_something).to receive(:cool_association_with).with(some: 123, other: 'sasd') { cool_association } |
@JonRowe I believe the job of the mocks framework should be to help me easily test my code in a readable fashion and not identify code smells. In my humble opinion there are far better tools for that job. Don't get me wrong, I appreciate the suggestion of the instance method but then I'll end up with a gazillion of those methods that I need to also test and all of a sudden RSpec is forcing me to write code that I shouldn't have to. |
So use my first suggestion and add the extra line of test, its also worth noting the |
I'm on the fence about this. On the one hand, I consider
If our suggestion to users is "keep using the old |
@JonRowe what about when I want to make sure that the following takes place with the right parameters? def create_transaction(options = {})
# do some processing with options.merge!({some other stuff})
account.transactions.create! options
end In a situation like that I don't care about what is done to collect the arguments I just care that the activerelation's Using stub_chain is not an option, that means I have to turn should syntax on and will end up having to get rid of other peoples should expectations all over again. That is something I really don't want. |
allow(account).to receive(:transactions)
expect(account.transactions).to receive(:create!).with(options) |
@JonRowe that is such an inconvenient way of writing that expectation. Had it not been so incredibly difficult to understand how the mock expectations work under the hood I would have written the code myself which I consider a truly good argument for why it should be available in the framework. Forcing people to write that extra allow statement when it wasn't needed before is not good enough in my humble opinion. |
Fwiw I think we should support: allow(object).to receive_chained_messages(:m1, :m2, :m3)
expect(object).to receive_chained_messages(:m1, :m2, :m3) and |
The last thing I want is users choosing not to upgrade to the newer syntax specifically because of the lack of a |
I'm with @myronmarston on the name @samphippen it sounds better to me, easier flow and easier to remember but I am native Swedish so I'm not sure I am allowed to even have an opinion on that. |
@samphippen is working on this in #467 |
Closing here since we'll be merging #467 very soon to address this :). |
I just upgraded to RSpec 3 and am totally in love with being forced to clean up all my deprecated mocks and expectations.
However there is one I am truly missing. While only used in a handful of places in every project I feel like it should truly be part of the framework. My reasoning for it is the following. While it may violate the law of demeter it is a very convenient way of making sure that some class receives the expected arguments. Take the following example:
Rather than stubbing the
fetch_something
method and return what I need I can ensure thatit
is only returned when the association receives the right arguments. I could refactor it into the belowThe above however won't guard me against accidentally deleting the line that actually does the fetching from the database. It also adds unnecessary complexity. I have to add another method just to verify the arguments are right and I still don't get the guard against accidental code deletion.
To get both I would have to refactor that into:
Now I get both validation and guard and while the law of demeter isn't violated I feel violated having to write this code. That is my case for having something like
receive_message_chain
as a native member of rspec-mocks.edit I realize I am mixing up the concepts a little with stub and expectations but there was no expectation on the stub_chain while I would if added use this with expectations to ensure that something calls the method chain using the right arguments. I would actually not stub it using allow.
The text was updated successfully, but these errors were encountered: