I am trying to unit test a method inside a model as shown below in rails. The whole aim is to do a database independent testing here and so thinking of using Factory girl.
For eg.,
Class A < ActiveRecord::Base
def self.method_A(param1,param2) do
/*do a select query on a table with param1 and param2*/
end
end
How to go about testing the method here with arguments here. Any help would be appreciated.
Yeah that looks correct. You kind of mock the class method and assert it
Related
I have trouble with trailblazer when setting up a simple show all Things view.
operation
class Thing < ApplicationRecord
class ShowAll < Trailblazer::Operation
include Model
model Thing, :all #why :all is not working here?
def process
end
end
end
controller
class PageController < ApplicationController
def index
run Word::ShowAll
end
end
why is :all not working for getting all Things from the db but :find works to get one via its id?
The best place to ask TRB questions is actually on Github channel.
I'm not sure where you found that example, as it is not supposed to work AFAIK, :find is a shortcut I believe, I've never actually used it.
All your logic should be defined inside the process method. http://trailblazer.to/gems/operation/1.1/api.html#process
Having said that, trying to get all records without some kind of pagination is a really bad idea, unless you are 100% sure that your table won't grow beyond several dozen records. Unless you know you don't have a large load. So to define that kind of shortcut is dangerous.
Calling Trailblazer::Model#model as you're doing there is just a shortcut for overriding the TrailBlazer::Operaration#model! method. So what you seem to want to do is:
class Thing < ApplicationRecord
class ShowAll < Trailblazer::Operation
def model!(params)
Thing.all # add any filtering or pagination here
end
end
end
And in your controller call present instead of run so that it sets up the model but doesn't call the process method of the operation.
class PageController < ApplicationController
def index
present Word::ShowAll
end
end
So I have a rails module called DbsfnpService.
Within this, I have a class
class DbnsfpAccess < ActiveRecord::Base
establish_connection :dbnsfp
end
I then have many methods within DbsfnpService similar to this.
def get_tables
sql = "select * from dbnsfp limit 1"
results = DbnsfpAccess.connection.execute(sql)
return results
end
When I call these methods from another class by including DbsnfpService, I would like to only establish one connection to :dbnsfp and handle all my queries and then close that connection. I believe how it is now, every method I call that contains DbsnfpAccess.connection.execute(sql) is making a separate connection(?). What is the best way to achieve this? Passing in a connection object into these functions? Thanks in advance!
If I'm understanding your question correctly, you want to execute calls on the database without knowing the table names and therefore unable to create rails ActiveRecord table models ahead of time.
Instead of executing sql you can use ActiveRecord::Base.connection.tables
(see this link How to list of all the tables defined for the database when using active record?)
To use these table names what you will need is to turn DbnsfpAccess into an abstract class.
class DbnsfpAccess < ActiveRecord::Base
self.abstract_class = true
establish_connection :dbnsfp
end
Then you can create the models you want to connect to DbnsfpAccess like this:
class DynamicallyGenratedDbnsfpModel << DbnsfpAccess
I am trying to learn Rspec in a very simple CRUD Rails 3.2.8 app. I'm following the general pattern of Michael Hartl's examples and have been moderately successful with cucumber for the outside in portion. Now I want to test a Twilio SMS feature and cannot seem to get to first base, mostly because I'm not asking the right questions, so I expect to be corrected here and get back on track.
My app has two models, commodity and price and they interact with each other in my cucumber tests, so it appears. I'm aware, like in cucumber, I need an object to start to test its interactions. In my prices controller, I see that I can get the commodity's prices with the below in my prices#create method:
#price = #commodity.prices.build(params[:price])
I ultimately want to generate a factory that will have many prices for a given commodity. But I want to get to base first. Following thoughtbot's examples on their Readme I'm attempting the following in rails console:
FactoryGirl.create(:commodity) do |price|
Commodity.prices.build(attributes_for(:price))
end
The result is: NoMethodError: undefined method `prices' for #
Hmm, I must not be understanding either Rspec or Factory Girl. Here is my basic factories.rb:
FactoryGirl.define do
factory :commodity do
name "corn"
end
sequence :price do |n|
price
date { Time.now }
end
end
Here are my two models:
class Commodity < ActiveRecord::Base
attr_accessible :description, :name
has_many :prices
end
MOST_RECENT = 5
class Price < ActiveRecord::Base
attr_accessible :buyer, :date, :price, :quality, :commodity_id
scope :most_recent, lambda { order("id desc").limit(MOST_RECENT) }
belongs_to :commodity
end
My attempt to understand this is to do it simply in Rails console but the error also appears when I run rspec as well. But why would FactoryGirl, or Rspec, not seem to use the prices method I get with Active Record? Clearly, I'm not understanding something or I would have found the answer on Stack, thanx, sam
In your FactoryGirl.create there are a couple problems. First, the block argument should be commodity, not price. create passes the created object into the block. Second, you're trying to run prices on the Commodity class. In your object relationship, prices is an accessor associated with a specific instance. There is no Commodity#prices method, but any given instance of Commodity will have prices. You can probably use build like that, but I think the canonical way is to use the shift operator to add a Price.
Putting this together gets you:
FactoryGirl.create(:commodity) do |commodity|
commodity.prices << FactoryGirl.create(:price, commodity: commodity)
end
I'm not sure what you're doing with the sequence in your Commodity factory definition. If you're trying to make sure that Commodities are created with Prices by default (without adding them as above), check out some of the tips at http://icelab.com.au/articles/factorygirl-and-has-many-associations/.
I am dealing with numerous calculations to bring various values within a model to a simple TRUE or FALSE. Problem is, these calculations are pretty intense and not something I want to create a long, hard to follow SQL statement for. I'd rather just have the entire calculation within a method that the model could check for when returning records.
I've tried numerous ways to accomplish this, and when looking up other similar feats, others push newbs like me to SQL which might serve most purposes but will not serve mine as the calculations being done are somewhat external to the model.
Model:
class Quality < ActiveRecord::Base
...
def passed_inspection
[code that calculates based on values in model]
end
Controller:
#records = Quality.where('passed_inspection = true')
View:
Did pass inspection?: <%= record.passed_inspection %>
It sounds like the solution to your problem would be to use a Scope with a Class Method to help clean up your model. Essentially you would set up your model like this:
class Quality < ActiveRecord::Base
def self.passed_inspection
# Code that does your calculations
end
scope :passed, passed_inspection() # This needs to be below the function above
end
Then you could get this data by calling it like this
#records = Quality.passed
There is a rails cast about this problem if you need any more information: RailsCast #215 Advanced Queries
Edit: Fixed some terrible grammar
I am using FactoryGirl in my rspec2 test with rails 3.2.1 and I would like to see the FactoryGirl output especially when the test fails.
Is there a way with $stderror puts to get to view what FactoryGirl has created?
Thanks
You could use the Rails logger to write directly to your log/test.log file.
I usually add the following to spec_helper.rb
def logger
Rails::logger
end
now you can log anywhere in your spec like so:
describe Customer do
it "logs factory girl generated objects" do
customer = Factory( :customer )
logger.warn( customer.pretty_inspect )
end
end
This will print the generated customer object with all properties