Hey Tim,

I can't remember exactly how but I am sure I had a oh I am doing it wrong 
moment and realised that the functionality works that I wanted.

I would suggest just reading up on rspec more because it definitely wasn't 
a fix in the code it was me understanding.


On Tuesday, 9 July 2019 06:38:09 UTC+12, Tim Boland wrote:
>
> Hi Jesse...
>
> Did you ever find a solution to this problem.  Im having the same issue.
>
> On Sunday, February 15, 2015 at 1:28:07 PM UTC-8, Jesse Whitham wrote:
>>
>> Absolutely not I will raise this there now. Thanks for the suggestion.
>>
>> On Friday, 13 February 2015 13:11:15 UTC+13, Jon Rowe wrote:
>>>
>>> Hi Jesse, would you mind opening an issue for `get ‘test’` not working 
>>> in a `before(:context)` over on `rspec-rails`? I’m not sure that it’s 
>>> fixable (due to the way Rails works) but if it isn’t we should probably 
>>> stop people from trying to do so.
>>>
>>> Jon Rowe
>>> ---------------------------
>>> [email protected]
>>> jonrowe.co.uk
>>>
>>> On Friday, 13 February 2015 at 08:39, Jesse Whitham wrote:
>>>
>>> Hi Myron,
>>>
>>> Thanks for your quick response. The feature you are talking about could 
>>> be very useful I would suggest that it would only provide what I would like 
>>> if it formats the expectation failures in a way that they are not just a 
>>> long string of different failures. In regards to the before(:context) hooks 
>>> I did look at this an option, and you are absolutely right about the 
>>> caveats in my case (testing an api) the get/post methods from rspec-rails 
>>> are not usable as below. 
>>>
>>> Failure/Error: get 'test'
>>>      RuntimeError:
>>>        @routes is nil: make sure you set it in your tests setup method.
>>>
>>>
>>> My hypothetical case of 100 expectations is really just being used to 
>>> emphasize the problem in reality I have a bunch of tests similar to this 
>>> that make more like 4-5 expectations but then if you expand it to look at 
>>> invalid user, disabled user and deleted user etc. you end up with a lot 
>>> more. Honestly it isn't a huge performance hit that make my tests take 
>>> hours and hours to run, but in saying that the more I write the worse it 
>>> will get. (By no way am I saying these tests are perfect I believe checking 
>>> it respects an XML format and is valid XML is probably superfluous)
>>>
>>>     context 'valid request' do
>>>       before do
>>>         @user = FactoryGirl.create(:authenticable_user)
>>>         # Not going to put the actual request here assume its something
>>>         post :api_request, request
>>>       end
>>>
>>>       it { expect(response).to be_ok }
>>>
>>>       describe 'with a valid user' do
>>>         it 'is a valid XML structure' do
>>>           expect { parse_xml(response.body) }.not_to raise_error
>>>         end
>>>         it 'is successful' do
>>>           expect(response.body).to include("success='true'")
>>>         end
>>>         it 'respects expected XML format' do
>>>           expect(response.body).to match_response_schema(
>>> 'login_response')
>>>         end
>>>         it 'contains a valid authentication token' do
>>>           auth_token = Nokogiri::XML(response.body).xpath(
>>> "//login_response").attribute("auth_token").value
>>>           expect(auth_token).to match(#A regex)
>>>         end
>>>       end
>>>
>>> Any way if you have hints etc. let me know. Honestly being able to use 
>>> before(:all) with post/get would fix this problem perfectly but from what 
>>> you have noted this seems not possible and may require some work on 
>>> rspec-raiils itself.
>>>
>>> Thanks,
>>> Jesse
>>>
>>> On Thursday, 12 February 2015 16:47:18 UTC+13, Myron Marston wrote:
>>>
>>> On Wednesday, February 11, 2015 at 7:23:13 PM UTC-8, Jesse Whitham wrote:
>>>
>>> So I ran into this problem with Testing our API.
>>>
>>> The problem is the get request is called multiple times based on 
>>> examples. e.g this code below will run get 'test' twice.
>>>
>>> require 'rails_helper'
>>>
>>> describe API::TestController, type: controller do
>>>   before do
>>>      get 'test'
>>>   end
>>>
>>>   it { expect(response).to be_ok }
>>>   it { expect(response.body).to eq('test code')end
>>>
>>> This is a problem when you start to have more expect statements in 
>>> terms of performance. As far as I know there is no good workarounds for 
>>> examples to re use the same response. The guide here
>>> http://betterspecs.org/#single talks about putting multiple expects 
>>> into the it statement, this seems to go against getting good failure 
>>> responses.
>>>
>>> Using a before(:all) you get an error like so
>>>
>>> Failure/Error: get 'test'
>>>      RuntimeError:
>>>        @routes is nil: make sure you set it in your tests setup method.
>>>
>>> Is there a way to send only one request without ruining the failure 
>>> responses?
>>> (or if you like use memoization over multiple examples)
>>>
>>> I did find you could use a global variable but this seems like the worst 
>>> code ever.
>>>
>>> require 'rails_helper'
>>>
>>> describe API::TestController, type: controller do
>>>   it 'makes a single request' do
>>>     get 'test'
>>>     $stupid_global = response
>>>   end
>>>   it { expect($stupid_global).to be_ok }
>>>   it { expect($stupid_global.body).to eq('test code')end
>>>
>>>
>>> I posted this here https://github.com/rspec/rspec-core/issues/1876 and 
>>> got this response:
>>>
>>> This conundrum (shared state vs performance is one of the reasons we 
>>> added compound matchers to RSpec 3.2, so you can now do:
>>>
>>>
>>> it { expect(response).to be_ok.and eq 'test code' }
>>>
>>>
>>> This isn't a complete solution of course but we don't want to advocate 
>>> shared state across examples.
>>>
>>> Incidentally Github issues are not the place to request support, please 
>>> use the mailing list / google group (https:
>>> //groups.google.com/forum/#!forum/rspec) and/or #rspec on freenode."
>>>
>>>
>>> I really don't see this as a even usable solution as if you have 100 
>>> expectations
>>>
>>>
>>> And you compound those you end up with failure in one string like so:
>>>
>>>
>>> Failure/Error: "we expected it to have this and  and we expected it to 
>>> have this and we expected it to have this and we expected it to have this 
>>> and we expected it to have this and we expected it to have this we 
>>> expected it to have this we expected it to have this we expected it to 
>>> have this we expected it to have this we expected it to have this we 
>>> expected it to have this"
>>>
>>> you don't compound them have one useless string with lots of 
>>> expectations 
>>>
>>> Failure/Error: "we expected the response to be ok (not sure why its 
>>> not)"
>>>
>>> or you make 100 requests (massive performance load).
>>>
>>> Does anyone have any suggestions for better ways? Alternative testing 
>>> frameworks? (maybe rspec just isn't useful for this kind of testing) or 
>>> even a feature for shared state? (By the sounds of it this will not be 
>>> supported)
>>>
>>>
>>>
>>> Hey Jesse,
>>>
>>> This is a great question. One solution, which has been available for 
>>> years, is to use a before(:context) (or before(:all) — that’s the old 
>>> RSpec 2.x form, and it still works in RSpec 3) hook. See, for example, this 
>>> PR 
>>> <https://github.com/rspec/rspec-support/pull/179/files#diff-ec40054ce667411396ff663c4d03bb50R65>
>>>  where 
>>> I’m doing a slow operation in before(:context), storing it in an 
>>> instance variable, making it available via some attr_reader declarations, 
>>> and using the results from multiple examples.
>>>
>>> Note, however that before(:context) hooks come with many caveats. (See 
>>> the “Warning: before(:context)” section from our docs 
>>> <http://rspec.info/documentation/3.2/rspec-core/RSpec/Core/Hooks.html#before-instance_method>).
>>>  
>>> The basic problem is that many things that integrate with RSpec — such as 
>>> DB transactions from DB cleaner or rspec-rails, or the rspec-mocks test 
>>> double life cycle — have a per-example life cycle, and running logic 
>>> *outside* of that lifecycle can cause problems. If you create DB 
>>> records in before(:context) and are using per-example DB transactions, 
>>> it would create the records and not clean them up afterwords, potentially 
>>> affecting later tests. So I’d say the before(:context) solution is 
>>> great as long as you don’t have per-example life cycle stuff going on. If 
>>> you do have that kind of stuff going on (and it’s very common to, 
>>> especially in a rails context) you’re better off avoiding 
>>> before(:context) or at least being extremely careful what you do in 
>>> there.
>>>
>>> I think the “one expectation per example” guideline is a useful 
>>> corrective to a pattern many first-time testers fall into, where they do 
>>> too much in one test or one example, and have hard-to-understand test 
>>> failures, but it's not something I recommend following strictly. 
>>> Personally, I use “one expectation per example” as a signal…if I’m putting 
>>> multiple expectations in one example I may be specifying multiple 
>>> behaviors. In fast, isolated unit tests you want to keep each example 
>>> focused on one behavior. In slower, integrated tests that’s far less 
>>> important, and the cost of the setup time (and different kind of test) 
>>> causes me to not worry about “one expectation per example”. If you are 
>>> doing slow integrated testing and the thing being is so complicated that it 
>>> needs 100 expectations (as per your hypothetical case), that suggests to me 
>>> that your logic could benefit from being refactored, with more of it being 
>>> extracted into stand-alone ruby objects that don’t interact with the slow 
>>> external things and can be quickly unit tested in isolation.
>>>
>>> One other thing I’ve been mulling over recently is a new feature in 
>>> RSpec that would better support what you’re trying to do. I’m thinking it 
>>> would be something like:
>>>
>>> it "returns a successful response" do
>>>   get 'test'
>>>   aggregate_failures do
>>>     expect(response).to be_ok
>>>     expect(response.body).to eq("test code")
>>>   endend
>>>
>>> The idea is that aggregate_failures (not necessarily what we’ll call it 
>>> — it’s the best name I’ve thought of so far, though) will change how 
>>> expect works for the duration of the block so that rather than aborting 
>>> on first failure, it collects all expectation failures until the end of the 
>>> example, and the block, and then, if there were any failures in the block, 
>>> it’ll abort at that point with all of the failure output.
>>>
>>> Would that do what you want?
>>>
>>> HTH,
>>> Myron 
>>>
>>> -- 
>>> 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 post to this group, send email to [email protected].
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/rspec/454ab805-c421-4ac8-a335-9a1f0e737653%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/rspec/454ab805-c421-4ac8-a335-9a1f0e737653%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>

-- 
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/fae8cf54-be70-4340-a98f-7da4b6e7c2dc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to