I'm trying to mock this statement, but I can't find anything on the internet to help me:
someone_ids = Office.join(:address, id: :address_id)
.join(:office_someone, id: :id)
.pluck(:someone_id)
Here is the spec that I'm using:
expect(Office).to receive(:join)
.with(:office_someone, { :id => :id })
.with(:address, { :id => :address_id })
.and_return([1])
Does anybody know how to mock multiple join? I'm using Sequel.
Previously RSpec had a stub_chain method that allowed you to do something like that easily, however it was removed because it encouraged bad practices, and now you'll have to stub each response manually:
office = instance_double(Office)
expect(Office).to receive(:join)
.with(:address, { :id => :address_id })
.and_return(office)
expect(office).to receive(:join)
.with(:office_someone, { :id => :id })
.and_return(office)
expect(office).to receive(:pluck).with(:someone_id).and_return([1])
Which if its a code that you find yourself repeating too much will made you think about refactoring it, which in the end is one of the reasons people do testing: "If its hard to test, it might not be well designed"
Related
Just wondering if it is possible to create a new GIT tag using Rugged. if so, an example would be greatly appreciated.
I'm basically just trying to create/move/delete tags on commit oids.
You can see some examples in test/tag_test.rb:
#repo = sandbox_init("testrepo.git")
#tag = #repo.tags.create('annotated_tag', "5b5b025afb0b4c913b4c338a42934a3863bf3644", {
:message => "test tag message\n",
:tagger => { :name => 'Scott', :email => 'schacon#gmail.com', :time => Time.now }
})
For deletion, see test/reference_test.rb:
tag = #repo.tags["test"]
#repo.references.delete(tag)
refute #repo.references.exists?("refs/tags/test")
The OP Chris Portman points out in the comments that:
The create/delete methods are actually part of the TagCollection class.
Same with branches and the BranchCollection class.
I'm new to Ruby, and I LOVE IT.
Playing around with Watir-Webdriver.
I want to store the reference to watir objects in a hash and save it to disk, WITHOUT having first defined the #browser variable.
For example
elements = {
:home => #browser.a(:href => /home.php/),
:photo => #browser.img(:id => "photo"),
:about => #browser.a(:href => /about.php/)
}
so that further I can do something like:
el = elements
el[:home].click
el[:photo].wait_until_present
el[:about].click
obviously this works if I define #browser at the very beginning..
#browser = Watir::Browser.new
but what if I want to store the 'elements' hash as YAML in a file?
Should I store the values as quoted strings and eval them on the fly? like
elements = {
:home => "#browser.a(:href => /home.php/)",
# etc...
}
# store elements as YAML file...
# load elements from YAML file
el = YAML::load_file "elements.yml"
eval(el[:home]).click
eval(el[:photo].wait_until_present
# etc...
is there a better way to do this?
Build a Class to provide access to #browser based on your YAML config.
Modify your elements structure to include the data you need rather than code. Consider this a config hash/file of sorts for your new Class.
elements = {
:home => { :tag => "a", :select => { :href => /home.php/ } },
:photo => { :tag => "img", :select => { :id => "photo" } },
:about => { :tag => "a", :select => { :href => /about.php/ } }
}
Build a class to load the elements YAML file and provide access to what you need from #browser based on what is loaded.
class WatirYamlBrowserSelect
# To store your config and browser.
attr_accessor :elements, :browser
def initialize elements_yaml_file
#elements = YAML.load_file elements_yaml_file
end
# Retrieve a configured element from Watir Browser.
def element name
#browser.send( #elements[name][:tag], #elements[name][:select] )
end
end
Then when you need to use it
# Create an instance of your selector.
s = WatirYamlBrowserSelect.new( "elements.yaml" )
# Add the browser when you have it
s.browser #browser
# Access the #browser elements
s.element :home
s.element :photo
s.element :about
Alister Scott's blog as well as its code in github was the template I used for building all the page objects for a few projects. I think it should solve the repetition issues you described. It also solves the problem of maintaining too many variables for too many pages of objects and keeps objects organized by page and not in a more complex data structure, especially when the number of objects increases.
http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/
http://watirmelon.com/2012/06/04/roll-your-own-page-objects/
https://github.com/alisterscott/wmf-custom-page-object
I have two objects, an #article and a #profile. Article is a model and #profile is a Struct. I'd like to end up with some JSON that looks like this:
{
"article": {
"title": "this is a title",
"author": "Author McAuthor",
"profile": {
"first_name": "Bobby",
"last_name": "Fisher"
}
}
}
As of now, I can just manually create this by doing something like:
#json = { article: { title: #article.title, author: #article.author, profile: { first_name: #profile.first_name, last_name: #profile.last_name } }}
I feel like building the json object this way is sorta crude, also, every time I change the author model, I might have to change this code. It would be great if I could find an easier way to build these json objects without having to do so manually... Any help? Thanks!
In addition to shioyama's correct answer, you can use rabl to craft your JSON objects, similar to how ERB works for views.
For example, you would create a 'view', say, index.rabl. It would look like:
collection #articles
attributes :author, :title
child(:profile) { attributes :first_name, :last_name }
Rails serializes objects in two steps, first by calling as_json to create the object to be serialized, then by calling to_json to actually create the JSON string.
Generally, if you want to customize how your models are represented in JSON, it's best to override as_json. Assuming your profile struct is a virtual attribute (i.e. defined with attr_accessor, not saved in the db), you could do this in your Article model:
def as_json(options = {})
super((options || {}).merge({
:methods => :profile
}))
end
Hope that helps. See also:
as_json documentation
Add virtual attribute to json output
I have a model that looks something like this:
class User
include Mongoid::Document
field :email
validate :email, presence: true, uniqueness: true
end
And I have a test that looks like...
it { User.new.should_not be_valid }
it { FactoryGirl.build(:user).should be_valid }
it { should validate_presence_of :email }
it { should validate_uniqueness_of :email }
Both of these want to hit the database when the .valid? method is called. Is there someway I can abstract that out? The uniqueness validator has been tested thoroughly by plenty of other folks, so the last line above is good enough for me.
Not that big a deal if I must run a DB during model specs, but I'd rather avoid it if possible.
The .valid? method should still work with ActiveModel, I am not quite sure what Mongoid includes but ActiveModel you must have include ActiveModel:Validations
This may not have been clear but ActiveModel does not try and hit the database.
I'm in the process of learning Sinatra and DataMapper. To do so, I've been playing with a "customer database" project.
Creating and deleting records is trivial and now I'm working on editing records. So far I've managed to piece together a form in my views and a couple of routes that I thought would edit a record. Here's some code to illustrate my issue:
My edit.erb view: http://gist.github.com/308405
My edit/update routes:
get '/edit/:acct' do
#title = "Edit Client Data"
#client = HE_Backend.get(params[:acct])
erb :edit
end
post '/update/:acct' do
client = HE_Backend.get(params[:acct])
client.attributes = {
:name => params['client']['name'],
:company => params['client']['company'],
:street => params['client']['street'],
:state => params['client']['state'],
:zip => params['client']['zip'],
:phone => params['client']['phone'],
:fax => params['client']['fax'],
:website => params['client']['website'],
:order_date => params['client']['order_date'],
:payment_date => params['client']['payment_date'],
:monthly => params['client']['monthly'],
:setup => params['client']['setup'],
:details => params['client']['details'],
:notes => params['client']['notes'],
:status => params['client']['status'],
}
if client.save
redirect "/show/#{client.acct}"
else
redirect('/list')
end
end
It looks like the "client.save" portion of the route is returning false, because I'm getting redirected to "/list" each time. If I use the #update method rather than #save, DM complains about "dirty records".
Anyone have any ideas as to what I'm doing wrong or can you point me to examples for editing records in SQLite with DataMapper and Sinatra?
Thanks!
This turned out to be a validations issue. If I don't have validations in place and put data types other than what's in my model in those fields, the #save method apparently returns false.