How I can parameterize to pass information between shared_example/include_examples?
In my specific case, I want to feed several constants to shared_example.
I found answer by myself... (I was hunting for answer for this two hours.. found this just after posting this)
At David Chelimsky's site, in article "Specifying mixins with shared example groups in RSpec-2," I found that shared_example can accept block parameters, and include_example can give parameters..
shared_example "example_1" do |param|
it "does something" do
xx.should == param
end
end
and later...
include_examples "example_1", :value_1
This work well with my case.
Note that, this parametalization is documented as cucumber feature, so I could find RSPec::Core document at Relish, but not in the class documentation.
Related
I have a monkeypatched of ActiveRecord find with some business logic, for example:
# lib/core_extensions/active_record/finder_methods/finder.rb
module ActiveRecord
module FinderMethods
def find(*args)
return super if block_given?
#... business logic code => my_error_control = true
raise "My Error" if my_error_control
retorn = find_with_ids(*args)
end
end
end
retorn
I have not seen many examples like this, and this causes me a doubt:
Where should finder.rb be?
In this example, this file is in lib/core_extensions/... but if it contains business logic, I think finder.rb should lives in the folder app/core_extensions/ isn't it?
Edited, after Sergio Answer
things like this, are a bad practice?
# lib/core_extensions/nil_class/image_attributes.rb
# suport for product images attributes
class NilClass
def main_image(size,evita_video)
"/images/paperclip_missing/original/missing.png"
end
end
Where should finder.rb be?
Ultimately, it doesn't matter. It only matters that this code gets loaded. This mix of patching base libraries and adding business logic there looks like something that MUST be documented thoroughly (in the project's wiki or something like that). And if it is documented, then it doesn't matter. The code is where the documentation says it is.
That being out of the way, here's a design suggestion:
when user seeks a Family Family.find(params[family_id],session[:company_id]), this find will compare the company of the family result family.company witht the parameter
Why not do something like this:
family = current_company.families.find(params[:family_id])
where current_company can be defined as #current_company ||= Company.find(session[:company_id])
Here, if this company doesn't have this family, you'll get an exception.
Same effect*, only without any patching. Much more futureproof. You can even add a couple of rubocop rules to ensure that you never write a naked Family.find.
* it's not like you add that patch and rest of your code magically acquires super-powers. No. You still have to change all the finders, to pass that company id.
It's the first time I see such case :). I'd put it in app/core_extensions and check if live reloading works correctly with it. If not, I'd move it to lib/. (It's just a heuristic)
Edit:
Instead of extending NilClass I'd rather use regular NullObjects. It's really less surprising and easier to understand.
https://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object
I have been using rspec for a little while and recently switched style from
it "should do something cool" do
#something.should work
end
to the more concise
subject(#something)
it {should work}
Whilst I much prefer the more concise style when writing the tests and for viewing them in code, I miss being able to specify the description for each test, particularly since the equality messages just display the values that are being tested. So in the example above, assuming the test passes, with the first style, I would get a message saying 'it should do something cool', whereas the second will just say that it has worked.
Does anyone know of a way to do this? Cheers
I think you got the wrong concept of what the specify/subject blocks do. They are not meant to be a complete replacement for the more verbose syntax you switched from, but should be used when there is no need for a desciption.
So if you want a desciption, just use
it "should do something cool" do
#something.should work
end
Also, I personally don't think that the specify/subject is more concise. For me it's a step away from the more DSL-like way specifications created with rspec read, but that might be a matter of personal preference.
I am using cucumber with rails, and I'm checking if the parent of an element has a certain class. I found this code, but it doesn't work. I'm using Capybara by the way. Thanks in advance!
Then the element "([^"]*)" with parent "([^"]*)" should have class "([^"]*)" do |element_id,parent,css_class|
response.should have_selector "#{parent} .#{css_class}" do |matches|
matches.should have_selector element_id
end
end
Technically, this isn't really the way you should be testing with cucumber. Cucumber is for testing behaviour, not checking the DOM - though of course it can be used in that way.
If you're really wanting to write something like this, you could make that much simpler:
Then /^the element "([^"]*)" with parent "([^"]*)" should have class "([^"]*)"$/ do |element_id,parent,css_class|
page.should have_css("#{parent}.#{css_class} #{element_id}")
end
This sucks on many levels, though. Not only are you checking the DOM directly from the step, which makes for very unreadable features, but you're mixing passing in element names, class names and element IDs - each with a slightly different style... In this step, element can be any type of selector whereas parent and css_class are much more fixed - they must always 'fit' into the selector string or it won't find anything.
I haven't really explained that very well, but in a nutshell, you should consider what you're actually trying to test and think whether it can be renamed to something more useful and re-usable. Would you ever be able to re-use that step without looking at it's implementation to figure out what goes where?
Also, with more expressive naming, the test instantly becomes more useful later down the line. For example, the step Then I should see the current list is active is much more readable and expressive than Then the element "li.active" with parent "ul" should have class "active-list". Be specific in the step definition implementation, not your features!
Have a read of this blog post - http://elabs.se/blog/15-you-re-cuking-it-wrong - it should give you a good idea of how to write better steps.
What's the best practices way to test that a model is valid in rails?
For example, if I have a User model that validates the uniqueness of an email_address property, how do I check that posting the form returned an error (or better yet, specifically returned an error for that field).
I feel like this should be something obvious, but as I'm quickly finding out, I still don't quite have the vocabulary required to effectively google ruby questions.
The easiest way would probably be:
class UserEmailAddressDuplicateTest < ActiveSupport::TestCase
def setup
#email = "test#example.org"
#user1, #user2 = User.create(:email => #email), User.new(:email => #email)
end
def test_user_should_not_be_valid_given_duplicate_email_addresses
assert !#user2.valid?
end
def test_user_should_produce_error_for_duplicate_email_address
# Test for the default error message.
assert_equal "has already been taken", #user2.errors.on(:email)
end
end
Of course it's possible that you don't want to create a separate test case for this behaviour, in which case you could duplicate the logic in the setup method and include it in both tests (or put it in a private method).
Alternatively you could store the first (reference) user in a fixture such as fixtures/users.yml, and simply instantiate a new user with a duplicate address in each test.
Refactor as you see fit!
http://thoughtbot.com/projects/shoulda/
Shoulda includes macros for testing things like validators along with many other things. Worth checking out for TDD.
errors.on is what you want
http://api.rubyonrails.org/classes/ActiveRecord/Errors.html#M002496
#obj.errors.on(:email) will return nil if field is valid, and the error messages either in a String or Array of Strings if there are one or more errors.
Testing the model via unit tests is, of course, step one. However, that doesn't necessarily guarantee that the user will get the feedback they need.
Section 4 of the Rails Guide on Testing has a lot of good information on functional testing (i.e. testing controllers and views). You have a couple of basic options here: check that the flash has a message in it about the error, or use assert_select to find the actual HTML elements that should have been generated in case of an error. The latter is really the only way to test that the user will actually get the message.
I am a total Groovy newbie. I saw the following code here.
def beforeInterceptor = [action:this.&auth,except:'login']
How would I expand this to also include a second exception, say, if the action was 'login2'?
Wow, would have expected a quick answer on this!
Well, found my own answer: you can't have more than one exception with except.
See the feature request here.
Instead, they recommend creating a Filter. See here.